|
|
|
mapboxgl.accessToken = 'pk.eyJ1Ijoic2hpMTEiLCJhIjoieGh5WE5ydyJ9.B7LtBt8hQixasCYHY9R_gA'; |
|
|
|
const map = new mapboxgl.Map({ |
|
container: 'map', |
|
projection: 'globe', |
|
center: [-30, 60], // starting center in [lng, lat] |
|
zoom: 1, |
|
pitch: 30, |
|
bearing: 0, |
|
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio |
|
style: 'mapbox://styles/mapbox/satellite-v9', |
|
interactive: false |
|
}); |
|
|
|
// Create a default Marker, colored black, rotated 45 degrees. |
|
const marker = new mapboxgl.Marker({ color: 'red', rotation: 15, scale:.75 }) |
|
.setLngLat([-73.75227480716791, 18.18979617487914]) |
|
.addTo(map); |
|
|
|
map.on('style.load', () => { |
|
map.setFog({}); // Set the default atmosphere style |
|
|
|
// Add terrain |
|
map.addSource('mapbox-dem', { |
|
'type': 'raster-dem', |
|
'url': 'mapbox://mapbox.mapbox-terrain-dem-v1', |
|
'tileSize': 512, |
|
'maxzoom': 14 |
|
}); |
|
map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 }); |
|
}); |
|
|
|
document.getElementById('fly').addEventListener('click', () => { |
|
// Fly to a random location |
|
map.flyTo({ |
|
center: [-73.75227480716791, 18.18979617487914], |
|
duration: 12000, // Animate over 12 seconds |
|
zoom: 14, |
|
essential: true // this animation is considered essential with respect to prefers-reduced-motion |
|
}); |
|
}); |
|
|
|
// At low zooms, complete a revolution every two minutes. |
|
const secondsPerRevolution = 120; |
|
// Above zoom level 5, do not rotate. |
|
const maxSpinZoom = 5; |
|
// Rotate at intermediate speeds between zoom levels 3 and 5. |
|
const slowSpinZoom = 3; |
|
|
|
let userInteracting = false; |
|
let spinEnabled = true; |
|
|
|
function spinGlobe() { |
|
const zoom = map.getZoom(); |
|
if (spinEnabled && !userInteracting && zoom < maxSpinZoom) { |
|
let distancePerSecond = 360 / secondsPerRevolution; |
|
if (zoom > slowSpinZoom) { |
|
// Slow spinning at higher zooms |
|
const zoomDif = |
|
(maxSpinZoom - zoom) / (maxSpinZoom - slowSpinZoom); |
|
distancePerSecond *= zoomDif; |
|
} |
|
const center = map.getCenter(); |
|
center.lng -= distancePerSecond; |
|
// Smoothly animate the map over one second. |
|
// When this animation is complete, it calls a 'moveend' event. |
|
map.easeTo({ center, duration: 1000, easing: (n) => n }); |
|
} |
|
} |
|
|
|
// Pause spinning on interaction |
|
map.on('mousedown', () => { |
|
userInteracting = true; |
|
}); |
|
|
|
// Restart spinning the globe when interaction is complete |
|
map.on('mouseup', () => { |
|
userInteracting = false; |
|
spinGlobe(); |
|
}); |
|
|
|
// These events account for cases where the mouse has moved |
|
// off the map, so 'mouseup' will not be fired. |
|
map.on('dragend', () => { |
|
userInteracting = false; |
|
spinGlobe(); |
|
}); |
|
map.on('pitchend', () => { |
|
userInteracting = false; |
|
spinGlobe(); |
|
}); |
|
map.on('rotateend', () => { |
|
userInteracting = false; |
|
spinGlobe(); |
|
}); |
|
|
|
// When animation is complete, start spinning if there is no ongoing interaction |
|
map.on('moveend', () => { |
|
spinGlobe(); |
|
}); |
|
|
|
spinGlobe(); |