161 lines
4.0 KiB
JavaScript
161 lines
4.0 KiB
JavaScript
// script.js
|
||
|
||
// 1️⃣ Your Mapbox access token
|
||
mapboxgl.accessToken = 'pk.eyJ1IjoiY2FiYmJ5eSIsImEiOiJjbWRpYzY1MGgwYzA5Mm1xM25udDUzbGtpIn0.RX6zv4VI6r2vpj7IWidz0w';
|
||
|
||
// 2️⃣ Initialize the map zoomed fully out (globe‑like)
|
||
const map = new mapboxgl.Map({
|
||
container: 'map',
|
||
style: 'mapbox://styles/mapbox/streets-v12',
|
||
center: [0, 0],
|
||
zoom: 1,
|
||
attributionControl: false
|
||
});
|
||
|
||
// 3️⃣ Define your companies ([lat, lng], zoom, imageUrl, description)
|
||
const companies = [
|
||
{
|
||
id: 'overview',
|
||
name: 'Overview',
|
||
coords: [40.14010599415405, -107.69483342077913],
|
||
zoom: 3,
|
||
imageUrl: 'images/wip.jpg',
|
||
description: `
|
||
<h2>Overview</h2>
|
||
<p>Use the controls in the top left corner to jump to a spot!</p>
|
||
`
|
||
},
|
||
{
|
||
id: 'tancha',
|
||
name: 'Tan‑Cha',
|
||
coords: [37.325382569107695, -122.01149036275054],
|
||
zoom: 9,
|
||
imageUrl: 'images/tancha.jpg',
|
||
description: `
|
||
<h2>Tan‑Cha</h2>
|
||
<p>Wip.</p>
|
||
`
|
||
},
|
||
{
|
||
id: 'pokehouse',
|
||
name: 'Poke House',
|
||
coords: [37.301113384436285, -121.9493462690826],
|
||
zoom: 9,
|
||
imageUrl: 'images/wip.jpg',
|
||
description: `
|
||
<h2>Poke House</h2>
|
||
<p>Wip.</p>
|
||
`
|
||
},
|
||
{
|
||
id: 'nanobase',
|
||
name: 'NanoBase',
|
||
coords: [34.68104506798117, 135.49167196036512],
|
||
zoom: 9,
|
||
imageUrl: 'images/work.jpg',
|
||
description: `
|
||
<h2>NanoBase</h2>
|
||
<p>Developed automated payroll processing scripts in Python, reducing errors by 85%.</p>
|
||
<a href="https://www.nanobase.co.jp/blogs/30">NanoBase Blog</a>
|
||
`
|
||
},
|
||
{
|
||
id: 'lanner',
|
||
name: 'Lanner Electronics',
|
||
coords: [43.69824981965482, -79.62570806485385],
|
||
zoom: 9,
|
||
imageUrl: 'images/wip.jpg',
|
||
description: `
|
||
<h2>Lanner Electronics</h2>
|
||
<p>Wip.</p>
|
||
`
|
||
}
|
||
];
|
||
|
||
// 4️⃣ Populate the company list
|
||
const listEl = document.getElementById('company-list');
|
||
companies.forEach((company, idx) => {
|
||
const btn = document.createElement('button');
|
||
btn.textContent = company.name;
|
||
btn.id = company.id;
|
||
btn.addEventListener('click', () => selectCompany(idx));
|
||
listEl.appendChild(btn);
|
||
});
|
||
|
||
// Holder for mapboxgl.Marker instances
|
||
const markers = [];
|
||
|
||
// Reference to the .map-wrapper for our fixed popups
|
||
const mapWrapper = document.querySelector('.map-wrapper');
|
||
|
||
/**
|
||
* Renders a fixed-position popup (does not move with the map)
|
||
*/
|
||
function showFixedPopup(company, [lng, lat]) {
|
||
// Remove any existing fixed popups
|
||
document.querySelectorAll('.fixed-popup').forEach(el => el.remove());
|
||
|
||
// Build the popup element
|
||
const popupEl = document.createElement('div');
|
||
popupEl.className = 'fixed-popup';
|
||
popupEl.innerHTML = `
|
||
<img
|
||
loading="lazy"
|
||
src="${company.imageUrl}"
|
||
alt="Me at ${company.name}" />
|
||
<strong>${company.name}</strong>
|
||
`;
|
||
|
||
// Attach into the map wrapper (above the map canvas)
|
||
mapWrapper.appendChild(popupEl);
|
||
}
|
||
|
||
/**
|
||
* Handles company selection:
|
||
* - cleans up old markers/popups
|
||
* - flies the map
|
||
* - updates the blurb
|
||
* - adds marker + fixed popup (if not overview)
|
||
*/
|
||
function selectCompany(index) {
|
||
const { coords, zoom, description, id } = companies[index];
|
||
const [lat, lng] = coords;
|
||
|
||
// Remove existing markers
|
||
markers.forEach(m => m.remove());
|
||
markers.length = 0;
|
||
|
||
// Remove any existing popups
|
||
document.querySelectorAll('.mapboxgl-popup, .fixed-popup').forEach(el => el.remove());
|
||
|
||
// Fly to the new location
|
||
map.flyTo({
|
||
center: [lng, lat],
|
||
zoom,
|
||
speed: 1.5,
|
||
essential: true
|
||
});
|
||
|
||
// Update the description blurb
|
||
document.getElementById('blurb').innerHTML = description;
|
||
|
||
// Highlight the active button
|
||
document.querySelectorAll('.company-list button')
|
||
.forEach(b => b.classList.toggle('active', b.id === id));
|
||
|
||
// If it's the overview, skip marker + popup
|
||
if (index === 0) return;
|
||
|
||
// Add a marker
|
||
const marker = new mapboxgl.Marker()
|
||
.setLngLat([lng, lat])
|
||
.addTo(map);
|
||
markers.push(marker);
|
||
|
||
// Show our custom fixed popup
|
||
showFixedPopup(companies[index], [lng, lat]);
|
||
}
|
||
|
||
// Initialize on load with the overview
|
||
selectCompany(0);
|