· 6 years ago · Feb 28, 2020, 10:24 PM
1mapboxgl.accessToken = '<private API key>';
2var map = new mapboxgl.Map({
3 container: 'map',
4 style: '<map base style>',
5 center: [0, 0],
6 zoom: 0,
7 bearing: 0,
8 pitch: 0.00001
9});
10
11map.on("load", function () {
12 // Insert the layer beneath any symbol layer.
13 var layers = map.getStyle().layers;
14
15 var labelLayerId;
16 for (var i = 0; i < layers.length; i++) {
17 if (layers[i].type === "symbol" && layers[i].layout["text-field"]) {
18 labelLayerId = layers[i].id;
19 break;
20 }
21 }
22
23 map.addLayer({
24 id: "3d-buildings",
25 source: "composite",
26 "source-layer": "building",
27 filter: ["==", "extrude", "true"],
28 type: "fill-extrusion",
29 minzoom: 17,
30 paint: {
31 "fill-extrusion-color": "#313131",
32
33 // use an 'interpolate' expression to add a smooth transition effect to the
34 // buildings as the user zooms in
35 "fill-extrusion-height": [
36 "interpolate", ["linear"],
37 ["zoom"],
38 17,
39 0,
40 20, ["get", "height"]
41 ],
42 "fill-extrusion-base": [
43 "interpolate", ["linear"],
44 ["zoom"],
45 17,
46 0,
47 20, ["get", "min_height"]
48 ],
49 "fill-extrusion-opacity": 0.8
50 }
51 },
52 labelLayerId
53 );
54});
55
56
57var chapters = {
58 'intro': {
59 center: [0, 0],
60 zoom: 0,
61 bearing: 0,
62 pitch: 0.00001
63 },
64
65 'par-lines-cut-transversal': {
66 bearing: 27,
67 center: [-122.200541, 37.751443],
68 zoom: 17,
69 bearing: 0,
70 pitch: 100
71 },
72 'perp-lines': {
73 center: [-122.390243, 37.790667],
74 bearing: 180,
75 zoom: 20
76 },
77 'trap': {
78 bearing: 0,
79 center: [-122.268278, 37.870059],
80 zoom: 20
81 },
82 'ss-interior': {
83 bearing: 180,
84 center: [-122.390243, 37.790667],
85 zoom: 20
86 },
87 'vert-angles': {
88 bearing: 90,
89 center: [-122.283443, 37.873951],
90 zoom: 20
91 },
92 'alt-exterior': {
93 bearing: 180,
94 center: [-122.390243, 37.790667],
95 zoom: 20
96 },
97 'angle-bisector': {
98 bearing: 90,
99 center: [-122.398831, 37.801154],
100 zoom: 20
101 },
102 'paral': {
103 bearing: 0,
104 center: [-73.994979, 40.704635],
105 zoom: 20
106 },
107 'cpct': {
108 bearing: 90,
109 center: [-0.126991, 51.519331],
110 zoom: 15
111 },
112 'rectangle': {
113 bearing: 100,
114 pitch: 100,
115 center: [-0.129478, 51.512019],
116 zoom: 20
117 }
118};
119
120// On every scroll event, check which element is on screen
121window.onscroll = function () {
122 var chapterNames = Object.keys(chapters);
123 for (var i = 0; i < chapterNames.length; i++) {
124 var chapterName = chapterNames[i];
125 if (isElementOnScreen(chapterName)) {
126 setActiveChapter(chapterName);
127 break;
128 }
129 }
130};
131
132var activeChapterName = 'intro';
133
134function setActiveChapter(chapterName) {
135 if (chapterName === activeChapterName) return;
136
137 map.flyTo(chapters[chapterName]);
138
139 document.getElementById(chapterName).setAttribute('class', 'active');
140 document.getElementById(activeChapterName).setAttribute('class', '');
141
142 activeChapterName = chapterName;
143}
144
145function isElementOnScreen(id) {
146 var element = document.getElementById(id);
147 var bounds = element.getBoundingClientRect();
148 return bounds.top < window.innerHeight && bounds.bottom > 0;
149}