UNPKG

nuxt-mapbox

Version:

Elegant Mapbox GL JS integration with Nuxt

88 lines (87 loc) 3.69 kB
import { whenever } from "@vueuse/core"; import { inject, isRef, onUnmounted, ref, useMapbox, useMapboxMarker, useMapboxMarkerRef, useState, watch } from "#imports"; import mapboxgl from "mapbox-gl"; export function defineMapboxMarker(markerID, options, markerHTML, callback, mapID = "") { if (import.meta.server) return; if (useMapboxMarkerRef(markerID).value) { console.warn(`Mapbox marker with ID '${markerID}' was initialized multiple times. This can cause unexpected behaviour.`); return useMapboxMarkerRef(markerID); } const markerRef = ref(); const mapId = inject("MapID"); function initMarker() { const markerOptions = isRef(options) ? options.value : options; if (markerHTML) { whenever(markerHTML, () => { if (markerHTML.value) { markerHTML.value.hidden = false; const mapbox_marker_instances = useState("mapbox_marker_instances", () => { return {}; }); mapbox_marker_instances.value[markerID] = new mapboxgl.Marker({ element: markerHTML.value, ...markerOptions }); markerRef.value = mapbox_marker_instances.value[markerID]; if (callback) callback(markerRef.value); useMapbox(mapId || mapID, (map) => { if (markerRef.value) markerRef?.value?.setLngLat(markerOptions.lnglat).addTo(map); }); } }, { immediate: true }); return markerRef; } else { const mapbox_marker_instances = useState("mapbox_marker_instances", () => { return {}; }); mapbox_marker_instances.value[markerID] = new mapboxgl.Marker(markerOptions); const marker = mapbox_marker_instances.value[markerID]; useMapbox(mapId || mapID, (map) => { marker.setLngLat(markerOptions.lnglat).addTo(map); }); return marker; } } if (isRef(options)) { watch(options, (newOptions, oldOptions) => { const currentMarker = useMapboxMarkerRef(markerID); if (newOptions.draggable !== oldOptions?.draggable && newOptions.draggable !== void 0) { currentMarker.value?.setDraggable(newOptions.draggable); } if (newOptions.offset !== oldOptions?.offset && newOptions.offset !== void 0) { currentMarker.value?.setOffset(newOptions.offset); } if (newOptions.pitchAlignment !== oldOptions?.pitchAlignment && newOptions.pitchAlignment !== void 0) { currentMarker.value?.setPitchAlignment(newOptions.pitchAlignment); } if (newOptions.rotationAlignment !== oldOptions?.rotationAlignment && newOptions.rotationAlignment !== void 0) { currentMarker.value?.setRotationAlignment(newOptions.rotationAlignment); } if (newOptions.rotation !== oldOptions?.rotation && newOptions.rotation !== void 0) { currentMarker.value?.setRotation(newOptions.rotation); } if (currentMarker.value?.getLngLat() !== options.value.lnglat) { currentMarker.value?.setLngLat(options.value.lnglat); } }, { deep: true }); useMapboxMarker(markerID, (marker) => { marker.on("drag", () => { const newLngLat = marker.getLngLat(); if (Array.isArray(options.value.lnglat)) { options.value.lnglat = newLngLat.toArray(); } else { options.value.lnglat = newLngLat; } }); }); } onUnmounted(() => { const currentMarker = useMapboxMarkerRef(markerID); if (currentMarker.value) { currentMarker.value.remove(); const mapbox_marker_instances = useState("mapbox_marker_instances", () => { return {}; }); delete mapbox_marker_instances.value[markerID]; } }); return initMarker(); }