1+ <template >
2+ <base-map :map-options =" mapOptions" @load =" handleMapLoaded" >
3+ <div class =" control" >
4+ <div class =" control-item" @click =" morph(-1)" >prev</div >
5+ <div class =" control-item" @click =" morph(1)" >next</div >
6+ </div >
7+ </base-map >
8+ </template >
9+
10+ <script setup lang="ts">
11+ import BaseMap from ' ../base-map.vue'
12+ import PolygonMorpher from ' @naivemap/mapbox-gl-polygon-morpher'
13+
14+ const mapOptions: Omit <mapboxgl .MapboxOptions , ' container' > = {
15+ center: [- 73.950543 , 40.76110 ],
16+ zoom: 11 ,
17+ }
18+
19+ const buildGeoJSONDistricts = (results ): GeoJSON .Feature <GeoJSON .Polygon | GeoJSON .MultiPolygon >[] => {
20+ return results .map ((row , i ) => {
21+ return {
22+ type: ' Feature' ,
23+ geometry: JSON .parse (row .boundary_simple ),
24+ properties: row
25+ }
26+ })
27+ }
28+
29+ let features: GeoJSON .Feature <GeoJSON .Polygon | GeoJSON .MultiPolygon >[]
30+ let polygonMorpher: PolygonMorpher
31+ let index = 0
32+
33+ const morph = (step : number ) => {
34+ index += step
35+ if (index < 0 ) {
36+ index = features .length + index
37+ }
38+ if (polygonMorpher && features .length > 0 ) {
39+ polygonMorpher .morph (features [index % features .length ])
40+ }
41+ }
42+
43+ const handleMapLoaded = (map : mapboxgl .Map ) => {
44+ map .addSource (' geojson-source' , {
45+ type: ' geojson' ,
46+ data: {
47+ type: ' FeatureCollection' ,
48+ features: [],
49+ },
50+ })
51+ map .addLayer (
52+ {
53+ id: ' poly-layer' ,
54+ type: ' fill' ,
55+ source: ' geojson-source' ,
56+ paint: {
57+ ' fill-color' : ' rgba(152, 224, 173, 0.5)' ,
58+ },
59+ },
60+ ' aeroway-line'
61+ )
62+ map .addLayer ({
63+ id: ' line-layer' ,
64+ type: ' line' ,
65+ source: ' geojson-source' ,
66+ paint: {
67+ ' line-width' : 2 ,
68+ ' line-color' : ' rgba(255, 178, 125, 1)' ,
69+ },
70+ })
71+
72+ const geojsonSource = map .getSource (' geojson-source' ) as mapboxgl .GeoJSONSource
73+ polygonMorpher = new PolygonMorpher (geojsonSource )
74+
75+ fetch (' https://us-congress-districts.api.aclu.org/pip?min_session=86&lat=40.7306&lng=-73.9866' )
76+ .then ((res ) => res .json ())
77+ .then ((data ) => {
78+ features = buildGeoJSONDistricts (data .results )
79+ polygonMorpher .morph (features [index ])
80+ })
81+ }
82+ </script >
83+
84+ <style lang="scss">
85+ .control {
86+ position : absolute ;
87+ right : 10px ;
88+ bottom : 38px ;
89+ border-radius : 4px ;
90+ background-color : rgba (255 , 255 , 255 , 0.8 );
91+ font-size : 12px ;
92+ font-weight : bold ;
93+ box-shadow : 0 0 0 2px rgba (0 , 0 , 0 , 0.1 );
94+
95+ & -item {
96+ padding : 4px 6px ;
97+ cursor : pointer ;
98+
99+ & :not (:last-child ) {
100+ border-bottom : 1.5px solid #ccc ;
101+ }
102+
103+ & :hover {
104+ background-color : rgba (0 , 0 , 0 , 0.1 );
105+ }
106+ }
107+ }
108+ </style >
0 commit comments