@@ -14,23 +14,23 @@ import { initZoomGuard } from "./zoom-guard";
1414import { initAbout } from "./about" ;
1515import { initCollectionDetails } from "./collection-details" ;
1616import { decodeState , encodeState , getRawDateFromDom } from "./url-state" ;
17+ import { exportMapImage } from "./export" ;
1718
1819initAbout ( ) ;
1920initCollectionDetails ( ) ;
2021
21- // Add share button to brand links
22- const shareBtn = document . createElement ( "button" ) ;
23- shareBtn . id = "share-btn" ;
24- shareBtn . textContent = "copy link" ;
22+ // Wire share button (pre-existing in HTML)
23+ const shareBtn = document . getElementById ( "share-btn" ) as HTMLButtonElement ;
2524shareBtn . addEventListener ( "click" , ( ) => {
2625 navigator . clipboard . writeText ( window . location . href ) . then ( ( ) => {
27- shareBtn . textContent = "copied!" ;
26+ shareBtn . title = "Copied!" ;
27+ shareBtn . style . color = "#64a0ff" ;
2828 setTimeout ( ( ) => {
29- shareBtn . textContent = "copy link" ;
29+ shareBtn . title = "Copy link" ;
30+ shareBtn . style . color = "" ;
3031 } , 2000 ) ;
3132 } ) ;
3233} ) ;
33- document . querySelector ( ".brand-links" ) ! . appendChild ( shareBtn ) ;
3434
3535const initialUrlState = decodeState ( ) ;
3636
@@ -39,9 +39,27 @@ const map = new maplibregl.Map({
3939 style : "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json" ,
4040 center : [ 0 , 20 ] ,
4141 zoom : 2 ,
42+ canvasContextAttributes : { preserveDrawingBuffer : true } ,
4243} ) ;
4344
4445map . addControl ( new maplibregl . NavigationControl ( ) , "bottom-right" ) ;
46+ map . addControl (
47+ new maplibregl . GeolocateControl ( {
48+ positionOptions : { enableHighAccuracy : true } ,
49+ fitBoundsOptions : { maxZoom : 10 } ,
50+ } ) ,
51+ "bottom-right"
52+ ) ;
53+
54+ document . getElementById ( "export-btn" ) ! . addEventListener ( "click" , ( ) => {
55+ const { collection, render } = getState ( ) ;
56+ const { datasetId } = getUrlMeta ( ) ;
57+ const rawDate = getRawDateFromDom ( collection . date . mode ) ;
58+ const dateStr = rawDate . s && rawDate . e
59+ ? `${ rawDate . s } _${ rawDate . e } `
60+ : ( rawDate . dt ?? undefined ) ;
61+ exportMapImage ( map , collection . attribution , datasetId , collection . slug , render . label , dateStr ) ;
62+ } ) ;
4563
4664let mapReady = false ;
4765
@@ -59,6 +77,8 @@ function updateUrl() {
5977 lng : parseFloat ( center . lng . toFixed ( 4 ) ) ,
6078 lat : parseFloat ( center . lat . toFixed ( 4 ) ) ,
6179 z : parseFloat ( map . getZoom ( ) . toFixed ( 2 ) ) ,
80+ b : parseFloat ( map . getBearing ( ) . toFixed ( 1 ) ) || undefined ,
81+ pt : parseFloat ( map . getPitch ( ) . toFixed ( 1 ) ) || undefined ,
6282 p :
6383 Object . keys ( state . extraParams ) . length > 0
6484 ? state . extraParams
@@ -106,6 +126,8 @@ map.on("load", () => {
106126 map . jumpTo ( {
107127 center : [ initialUrlState . lng , initialUrlState . lat ] ,
108128 zoom : initialUrlState . z ,
129+ bearing : initialUrlState . b ?? 0 ,
130+ pitch : initialUrlState . pt ?? 0 ,
109131 } ) ;
110132 }
111133
@@ -117,3 +139,11 @@ map.on("load", () => {
117139map . on ( "moveend" , ( ) => {
118140 if ( mapReady ) updateUrl ( ) ;
119141} ) ;
142+
143+ map . on ( "rotateend" , ( ) => {
144+ if ( mapReady ) updateUrl ( ) ;
145+ } ) ;
146+
147+ map . on ( "pitchend" , ( ) => {
148+ if ( mapReady ) updateUrl ( ) ;
149+ } ) ;
0 commit comments