diff --git a/website/src/lib/components/InteractiveMap.svelte b/website/src/lib/components/InteractiveMap.svelte index bacd286..a4694bd 100644 --- a/website/src/lib/components/InteractiveMap.svelte +++ b/website/src/lib/components/InteractiveMap.svelte @@ -5,6 +5,42 @@ import { themeState } from '$lib/states/theme.svelte'; import 'maplibre-gl/dist/maplibre-gl.css'; + function addMapLayers(map: any, isLight: boolean) { + if (!map.getSource('study-locations')) { + map.addSource('study-locations', { + type: 'geojson', + data: { + type: 'FeatureCollection', + features: UMD_LOCATIONS.map(loc => ({ + type: 'Feature', + geometry: { type: 'Point', coordinates: [loc.lng, loc.lat] }, + properties: { name: loc.name } + })) + } + }); + } + + if (!map.getLayer('study-locations-labels')) { + map.addLayer({ + id: 'study-locations-labels', + type: 'symbol', + source: 'study-locations', + layout: { + 'text-field': ['get', 'name'], + 'text-size': 13, + 'text-variable-anchor': ['top', 'bottom', 'left', 'right'], + 'text-radial-offset': 1, + 'text-justify': 'center' + }, + paint: { + 'text-color': isLight ? '#1e1e2e' : '#ffffff', + 'text-halo-color': isLight ? '#ffffff' : '#000000', + 'text-halo-width': 2 + } + }); + } + } + let mapContainer: HTMLDivElement | undefined = $state(); let mapInstance: any = $state(); @@ -25,98 +61,73 @@ $effect(() => { if (mapInstance) { - const style = themeState.isLight + const isLight = themeState.isLight; + const style = isLight ? 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json' : 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json'; - untrack(() => { mapInstance.setStyle(style); }); + untrack(() => { + mapInstance.setStyle(style); + mapInstance.once('style.load', () => addMapLayers(mapInstance, isLight)); + }); } }); - onMount(async () => { - if (!browser || !mapContainer) return; - - const { Map, NavigationControl } = await import('maplibre-gl'); + onMount(() => { + if (!browser || !mapContainer) return; - const map = new Map({ - container: mapContainer, - style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json', - center: [-76.9425, 38.9859], // UMD McKeldin Mall - zoom: 16.5, - pitch: 0, - bearing: 0, - attributionControl: false - }); + let map: any; - map.addControl(new NavigationControl({ - visualizePitch: true - }), 'bottom-right'); + (async () => { + const { Map, NavigationControl } = await import('maplibre-gl'); - mapInstance = map; + map = new Map({ + container: mapContainer!, + style: themeState.isLight + ? 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json' + : 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json', + center: [-76.9425, 38.9859], + zoom: 16.5, + pitch: 0, + bearing: 0, + attributionControl: false + }); - map.on('load', () => { - map.addSource('study-locations', { - type: 'geojson', - data: { - type: 'FeatureCollection', - features: UMD_LOCATIONS.map(loc => ({ - type: 'Feature', - geometry: { type: 'Point', coordinates: [loc.lng, loc.lat] }, - properties: { name: loc.name } - })) - } - }); + map.addControl(new NavigationControl({ visualizePitch: true }), 'bottom-right'); + mapInstance = map; - map.addLayer({ - id: 'study-locations-labels', - type: 'symbol', - source: 'study-locations', - layout: { - 'text-field': ['get', 'name'], - 'text-size': 13, - 'text-variable-anchor': ['top', 'bottom', 'left', 'right'], - 'text-radial-offset': 1, - 'text-justify': 'center' - }, - paint: { - 'text-color': '#ffffff', - 'text-halo-color': '#000000', - 'text-halo-width': 2 - } - }); - }); + map.on('load', () => addMapLayers(map, themeState.isLight)); + })(); return () => { - map.remove(); + map?.remove(); }; });