|
3 | 3 | <head>
|
4 | 4 | <title>Mapbox GL JS debug page</title>
|
5 | 5 | <meta charset='utf-8'>
|
6 |
| - <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> |
| 6 | + <meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'> |
7 | 7 | <link rel='stylesheet' href='../dist/mapbox-gl.css' />
|
8 | 8 | <style>
|
9 | 9 | body { margin: 0; padding: 0; }
|
|
20 | 20 |
|
21 | 21 | var map = window.map = new mapboxgl.Map({
|
22 | 22 | container: 'map',
|
23 |
| - devtools: true, |
24 |
| - zoom: 12.5, |
25 |
| - center: [-122.4194, 37.7749], |
| 23 | + zoom: 16.7, |
| 24 | + center: [24.9425, 60.1715], |
| 25 | + pitch: 67, |
| 26 | + bearing: -34, |
26 | 27 | hash: true,
|
27 | 28 | style: 'mapbox://styles/mapbox-map-design/standard-experimental-ime',
|
28 | 29 | });
|
29 | 30 |
|
30 |
| - |
31 |
| -// Selecting buildings |
32 |
| -var selectedBuildings = []; |
| 31 | +// Selecting Buildings |
| 32 | +let selectedBuildings = []; |
33 | 33 | map.addInteraction('building-click', {
|
34 | 34 | type: 'click',
|
35 |
| - featureset: {featuresetId: "buildings", importId: "basemap"}, |
| 35 | + featureset: {featuresetId: 'buildings', importId: 'basemap'}, |
36 | 36 | handler: (e) => {
|
37 |
| - // Clear selected building |
38 |
| - selectedBuildings.forEach(f => map.setFeatureState(f, {select: false})); |
39 |
| - |
40 |
| - map.setFeatureState(e.feature, {select: true}); |
41 |
| - selectedBuildings = [e.feature]; |
| 37 | + map.setFeatureState(e.feature, {select: !e.feature.state.select}); |
| 38 | + selectedBuildings.push(e.feature); |
42 | 39 | }
|
43 | 40 | });
|
44 | 41 |
|
45 | 42 | // Selecting POIs
|
46 |
| -var selectedPoi = null; |
47 |
| -const selectedPoiMarker = new mapboxgl.Marker(); |
48 |
| -selectedPoiMarker.getElement().style.cursor = 'pointer'; |
| 43 | +let selectedPoi = null; |
| 44 | +const poiMarker = new mapboxgl.Marker({color: 'red'}); |
| 45 | +poiMarker.getElement().style.cursor = 'pointer'; |
| 46 | + |
49 | 47 | map.addInteraction('poi-click', {
|
50 | 48 | type: 'click',
|
51 |
| - featureset: {featuresetId: "poi", importId: "basemap"}, |
| 49 | + featureset: {featuresetId: 'poi', importId: 'basemap'}, |
52 | 50 | handler: (e) => {
|
53 |
| - console.log("poi click", e.feature); |
54 |
| - if(selectedPoi) { |
| 51 | + if (selectedPoi) { |
55 | 52 | map.setFeatureState(selectedPoi, {hide: false});
|
56 |
| - selectedPoiMarker.remove(); |
| 53 | + poiMarker.remove(); |
57 | 54 | }
|
58 | 55 |
|
59 | 56 | selectedPoi = e.feature;
|
60 |
| - selectedPoiMarker |
61 |
| - .setLngLat(e.feature.geometry.coordinates) |
| 57 | + poiMarker |
| 58 | + .setLngLat(selectedPoi.geometry.coordinates) |
62 | 59 | .addTo(map);
|
63 | 60 |
|
64 | 61 | let html = '';
|
65 | 62 | for (const key in e.feature.properties) {
|
66 | 63 | html += `<div><b>${key}</b>: ${e.feature.properties[key]}</div>`;
|
67 | 64 | }
|
68 |
| - selectedPoiMarker.setPopup(new mapboxgl.Popup().setHTML(html)); |
| 65 | + |
| 66 | + const popup = new mapboxgl.Popup().setHTML(html); |
| 67 | + poiMarker.setPopup(popup); |
69 | 68 |
|
70 | 69 | map.setFeatureState(e.feature, {hide: true});
|
71 | 70 |
|
72 |
| - /// Optional: Highlight buildins underneath the selected pin. |
73 |
| - // TODO: Uncomment after GLJS-1062 |
74 |
| - // let buildings = map.queryRenderedFeatures({ |
75 |
| - // featureset: {featuresetId: "buildings", importId: "basemap"}, |
76 |
| - // filter: ["<=", ["distance", e.feature.geometry], 0] |
77 |
| - // }) |
78 |
| - // buildings.forEach(f => map.setFeatureState(f, {select: true})); |
79 |
| - // selectedBuildings = buildings; |
| 71 | + // Highlight buildins underneath the selected pin. |
| 72 | + const buildings = map.queryRenderedFeatures({ |
| 73 | + featureset: {featuresetId: 'buildings', importId: 'basemap'}, |
| 74 | + filter: ['<=', ['distance', e.feature.geometry], 0] |
| 75 | + }); |
| 76 | + |
| 77 | + if (buildings.length > 0) { |
| 78 | + selectedBuildings.forEach(f => map.setFeatureState(f, {select: false})); |
| 79 | + buildings.forEach(f => map.setFeatureState(f, {select: true})); |
| 80 | + selectedBuildings = buildings; |
| 81 | + } |
80 | 82 | }
|
81 | 83 | });
|
82 | 84 |
|
83 |
| -// Selecting places |
84 |
| -var selectedPlace = null; |
85 |
| -var placePopup = new mapboxgl.Popup(); |
| 85 | +// Selecting Places |
| 86 | +let selectedPlace = null; |
| 87 | +let placePopup = new mapboxgl.Popup(); |
86 | 88 | map.addInteraction('place-click', {
|
87 | 89 | type: 'click',
|
88 |
| - featureset: {featuresetId: "place-labels", importId: "basemap"}, |
| 90 | + featureset: {featuresetId: 'place-labels', importId: 'basemap'}, |
89 | 91 | handler: (e) => {
|
90 |
| - console.log("place click", e.feature); |
91 |
| - if(selectedPlace) { |
| 92 | + if (selectedPlace) { |
92 | 93 | map.setFeatureState(selectedPlace, {select: false});
|
93 | 94 | }
|
94 | 95 |
|
|
99 | 100 | for (const key in e.feature.properties) {
|
100 | 101 | html += `<div><b>${key}</b>: ${e.feature.properties[key]}</div>`;
|
101 | 102 | }
|
| 103 | + |
102 | 104 | placePopup
|
103 | 105 | .setLngLat(e.feature.geometry.coordinates)
|
104 | 106 | .setHTML(html)
|
105 | 107 | .addTo(map);
|
106 | 108 | }
|
107 | 109 | });
|
108 | 110 |
|
109 |
| -// Cleaning selected features |
| 111 | +// Clearing features selection |
110 | 112 | map.addInteraction('map-click', {
|
111 | 113 | type: 'click',
|
112 | 114 | handler: (e) => {
|
113 | 115 | // Clear selected POI
|
114 |
| - if(selectedPoi) { |
| 116 | + if (selectedPoi) { |
115 | 117 | map.setFeatureState(selectedPoi, {hide: false});
|
116 |
| - selectedPoiMarker.remove(); |
| 118 | + poiMarker.remove(); |
117 | 119 | selectedPoi = null;
|
118 | 120 | }
|
119 | 121 |
|
120 | 122 | // Clear selected building
|
121 | 123 | selectedBuildings.forEach(f => map.setFeatureState(f, {select: false}));
|
122 | 124 |
|
123 | 125 | // Clear selected place
|
124 |
| - if(selectedPlace) { |
| 126 | + if (selectedPlace) { |
125 | 127 | map.setFeatureState(selectedPlace, {select: false});
|
126 | 128 | selectedPlace = null;
|
127 | 129 | }
|
| 130 | + |
128 | 131 | placePopup.remove();
|
129 | 132 | return false;
|
130 | 133 | }
|
131 | 134 | });
|
132 | 135 |
|
133 | 136 | // Hover effects
|
134 | 137 |
|
135 |
| -var hoveredBuilding = null; |
136 |
| -var hoveredPlace = null; |
137 |
| - |
138 |
| -function highlight(feature, hovered) { |
139 |
| - if (hovered) { |
140 |
| - map.setFeatureState(feature, {highlight: true}); |
141 |
| - } else { |
142 |
| - map.setFeatureState(feature, {highlight: false}); |
143 |
| - } |
144 |
| -} |
145 |
| - |
146 |
| -map.addInteraction('building-hover', { |
| 138 | +let hoveredBuilding; |
| 139 | +map.addInteraction('building-mousemove', { |
147 | 140 | type: 'mousemove',
|
148 |
| - featureset: {featuresetId: "buildings", importId: "basemap"}, |
| 141 | + featureset: {featuresetId: 'buildings', importId: 'basemap'}, |
149 | 142 | handler: (e) => {
|
150 | 143 | if (hoveredBuilding) {
|
151 |
| - if(hoveredBuilding.id === e.feature.id && hoveredBuilding.namespace === e.feature.namespace) { |
152 |
| - // Hovering the same building |
153 |
| - return; |
154 |
| - } |
| 144 | + // Hovering the same building |
| 145 | + if(hoveredBuilding.id === e.feature.id && hoveredBuilding.namespace === e.feature.namespace) return; |
155 | 146 | // Clear the old building highlight
|
156 |
| - highlight(hoveredBuilding, false); |
157 |
| - } |
158 |
| - |
159 |
| - if (hoveredPlace) { |
160 |
| - // Clear the place highlight |
161 |
| - highlight(hoveredPlace, false); |
162 |
| - hoveredBuilding = null; |
| 147 | + map.setFeatureState(hoveredBuilding, {highlight: false}); |
163 | 148 | }
|
164 | 149 |
|
165 | 150 | hoveredBuilding = e.feature;
|
166 |
| - highlight(hoveredBuilding, true); |
167 |
| - map.getCanvas().style.cursor = 'pointer'; |
168 |
| - } |
169 |
| -}); |
170 |
| - |
171 |
| -map.addInteraction('place-hover', { |
172 |
| - type: 'mousemove', |
173 |
| - featureset: {featuresetId: "place-labels", importId: "basemap"}, |
174 |
| - handler: (e) => { |
175 |
| - if (hoveredPlace) { |
176 |
| - if(hoveredPlace.id === e.feature.id && hoveredPlace.namespace === e.feature.namespace) { |
177 |
| - // Hovering the same place |
178 |
| - return; |
179 |
| - } |
180 |
| - // Clear the old place highlight |
181 |
| - highlight(hoveredPlace, false); |
182 |
| - } |
183 |
| - |
184 |
| - if (hoveredBuilding) { |
185 |
| - // Clear the building highlight |
186 |
| - highlight(hoveredBuilding, false); |
187 |
| - hoveredBuilding = null; |
188 |
| - } |
189 |
| - |
190 |
| - hoveredPlace = e.feature; |
191 |
| - highlight(hoveredPlace, true); |
192 |
| - map.getCanvas().style.cursor = 'pointer'; |
| 151 | + map.setFeatureState(e.feature, {highlight: true}); |
193 | 152 | }
|
194 | 153 | });
|
195 | 154 |
|
196 |
| -// Mousemove on map that wasn't handled any featureset-specific interaction |
197 |
| -// means the mouse is moved outside of hovered features. |
198 |
| -// Thid is a safe place to clear the hover effect. |
199 |
| -map.addInteraction(`map-mousemove`, { |
200 |
| - type: 'mousemove', |
| 155 | +map.addInteraction('building-mouseleave', { |
| 156 | + type: 'mouseleave', |
| 157 | + featureset: {featuresetId: 'buildings', importId: 'basemap'}, |
201 | 158 | handler: (e) => {
|
202 | 159 | if (hoveredBuilding) {
|
203 |
| - highlight(hoveredBuilding, false); |
| 160 | + map.setFeatureState(hoveredBuilding, {highlight: false}); |
204 | 161 | hoveredBuilding = null;
|
205 | 162 | }
|
206 |
| - |
207 |
| - if (hoveredPlace) { |
208 |
| - highlight(hoveredPlace, false); |
209 |
| - hoveredPlace = null; |
210 |
| - } |
211 |
| - map.getCanvas().style.cursor = ''; |
212 |
| - return false; // Don't stop the event propagation. |
213 | 163 | }
|
214 | 164 | });
|
215 | 165 |
|
|
0 commit comments