-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapbox.html
145 lines (128 loc) · 4.42 KB
/
mapbox.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Create a rotating globe</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.11.0/mapbox-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<style>
#btn-spin {
font: bold 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
background-color: #3386c0;
color: #fff;
position: absolute;
top: 20px;
left: 50%;
z-index: 1;
border: none;
width: 200px;
margin-left: -100px;
display: block;
cursor: pointer;
padding: 10px 20px;
border-radius: 3px;
}
#btn-spin:hover {
background-color: #4ea0da;
}
</style>
<div id="map"></div>
<button id="btn-spin">Pause rotation</button>
<script>
mapboxgl.accessToken = 'pk.eyJ1Ijoiaml1dHUiLCJhIjoiY2w0dHlwYTh1MDJrOTNpcWV0cm5iYjUxMSJ9.HvKZegWShj5yuoAPqt5T2w';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
projection: 'globe', // Display the map as a globe, since satellite-v9 defaults to Mercator
zoom: 1.5,
center: [-90, 40]
});
map.on('style.load', () => {
map.setFog({}); // Set the default atmosphere style
});
// The following values can be changed to control rotation speed:
// 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();
});
document.getElementById('btn-spin').addEventListener('click', (e) => {
spinEnabled = !spinEnabled;
if (spinEnabled) {
spinGlobe();
e.target.innerHTML = 'Pause rotation';
} else {
map.stop(); // Immediately end ongoing animation
e.target.innerHTML = 'Start rotation';
}
});
spinGlobe();
</script>
</body>
</html>