99 lines
2.9 KiB
JavaScript
99 lines
2.9 KiB
JavaScript
/**
|
|
* Contact Info map module.
|
|
*/
|
|
|
|
const MAP_SELECTOR = '.contact-info__map[data-lat][data-lng]';
|
|
const DEFAULT_ZOOM = 14;
|
|
const MARKER_SIZE = [62, 68];
|
|
|
|
let leafletModulePromise;
|
|
|
|
function loadLeaflet() {
|
|
if (!leafletModulePromise) {
|
|
leafletModulePromise = import('https://unpkg.com/leaflet@1.9.4/dist/leaflet-src.esm.js');
|
|
}
|
|
|
|
return leafletModulePromise;
|
|
}
|
|
|
|
function toFloat(value) {
|
|
const parsed = Number.parseFloat(value);
|
|
|
|
return Number.isFinite(parsed) ? parsed : null;
|
|
}
|
|
|
|
export async function initContactInfoMap() {
|
|
const mapContainers = document.querySelectorAll(MAP_SELECTOR);
|
|
|
|
if (!mapContainers.length) {
|
|
return;
|
|
}
|
|
|
|
let Leaflet;
|
|
|
|
try {
|
|
const module = await loadLeaflet();
|
|
Leaflet = module.default || module;
|
|
} catch (error) {
|
|
console.error('Leaflet failed to load for contact map.', error);
|
|
return;
|
|
}
|
|
|
|
mapContainers.forEach((container) => {
|
|
if (container.dataset.mapReady === 'true') {
|
|
return;
|
|
}
|
|
|
|
const latitude = toFloat(container.dataset.lat);
|
|
const longitude = toFloat(container.dataset.lng);
|
|
const zoom = toFloat(container.dataset.zoom) || DEFAULT_ZOOM;
|
|
|
|
if (latitude === null || longitude === null) {
|
|
return;
|
|
}
|
|
|
|
const map = Leaflet.map(container, {
|
|
zoomControl: false,
|
|
scrollWheelZoom: false,
|
|
dragging: false,
|
|
doubleClickZoom: false,
|
|
boxZoom: false,
|
|
keyboard: false,
|
|
tap: false,
|
|
attributionControl: true,
|
|
}).setView([latitude, longitude], zoom);
|
|
|
|
Leaflet.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
|
|
maxZoom: 19,
|
|
subdomains: 'abcd',
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
|
|
}).addTo(map);
|
|
|
|
const markerSvg = container.dataset.markerSvg;
|
|
|
|
const markerIcon = markerSvg
|
|
? Leaflet.divIcon({
|
|
className: 'contact-info__leaflet-pin',
|
|
html: markerSvg,
|
|
iconSize: MARKER_SIZE,
|
|
iconAnchor: [MARKER_SIZE[0] / 2, MARKER_SIZE[1]],
|
|
})
|
|
: Leaflet.icon({
|
|
iconUrl: container.dataset.marker || '',
|
|
iconSize: MARKER_SIZE,
|
|
iconAnchor: [MARKER_SIZE[0] / 2, MARKER_SIZE[1]],
|
|
popupAnchor: [0, -MARKER_SIZE[1] + 8],
|
|
className: 'contact-info__leaflet-pin'
|
|
});
|
|
|
|
const marker = Leaflet.marker([latitude, longitude], { icon: markerIcon }).addTo(map);
|
|
const popupText = container.dataset.popup;
|
|
|
|
if (popupText) {
|
|
marker.bindPopup(popupText);
|
|
}
|
|
|
|
container.dataset.mapReady = 'true';
|
|
});
|
|
}
|