mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-08-24 15:28:57 +00:00
88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
/**
|
|
* Mapbox GL integration for FixIt shortcode blocks.
|
|
*
|
|
* Responsibilities:
|
|
* - Initialize Mapbox GL maps with controls and optional markers.
|
|
* - Apply light/dark style on theme switch.
|
|
* - Re-run initialization when `fixit:content-decrypted` is emitted.
|
|
*/
|
|
import { eventBus } from '../core/event-bus'
|
|
import { isDarkMode } from '../utils'
|
|
|
|
const mapboxArr: any[] = []
|
|
|
|
function initMapbox(target: Element | Document = document) {
|
|
const mapboxgl = window.mapboxgl
|
|
const MapboxLanguage = window.MapboxLanguage
|
|
const config = window.config.mapbox
|
|
if (!mapboxgl || !config)
|
|
return
|
|
if (!mapboxgl.accessToken) {
|
|
mapboxgl.accessToken = config.accessToken!
|
|
mapboxgl.setRTLTextPlugin(config.RTLTextPlugin!)
|
|
}
|
|
const isDark = isDarkMode()
|
|
target.querySelectorAll<HTMLElement>('.mapbox:empty').forEach(($mapbox) => {
|
|
const { lng, lat, zoom, lightStyle, darkStyle, marked, markers, navigation, geolocate, scale, fullscreen } = JSON.parse($mapbox.dataset.options!)
|
|
const mapbox = new mapboxgl.Map({
|
|
container: $mapbox,
|
|
center: [lng, lat],
|
|
zoom,
|
|
minZoom: 0.2,
|
|
style: isDark ? darkStyle : lightStyle,
|
|
attributionControl: false,
|
|
})
|
|
if (marked) {
|
|
new mapboxgl.Marker().setLngLat([lng, lat]).addTo(mapbox)
|
|
}
|
|
const markerArray = typeof markers === 'string' ? JSON.parse(markers) : markers
|
|
if (Array.isArray(markerArray) && markerArray.length > 0) {
|
|
markerArray.forEach((marker: any) => {
|
|
const { lng: markerLng, lat: markerLat, description } = marker
|
|
const popup = new mapboxgl.Popup({ offset: 25 }).setText(description)
|
|
new mapboxgl.Marker()
|
|
.setLngLat([markerLng, markerLat])
|
|
.setPopup(popup)
|
|
.addTo(mapbox)
|
|
})
|
|
}
|
|
if (navigation) {
|
|
mapbox.addControl(new mapboxgl.NavigationControl(), 'bottom-right')
|
|
}
|
|
if (geolocate) {
|
|
mapbox.addControl(
|
|
new mapboxgl.GeolocateControl({
|
|
positionOptions: { enableHighAccuracy: true },
|
|
showUserLocation: true,
|
|
trackUserLocation: true,
|
|
}),
|
|
'bottom-right',
|
|
)
|
|
}
|
|
if (scale) {
|
|
mapbox.addControl(new mapboxgl.ScaleControl())
|
|
}
|
|
if (fullscreen) {
|
|
mapbox.addControl(new mapboxgl.FullscreenControl())
|
|
}
|
|
mapbox.addControl(new MapboxLanguage())
|
|
mapboxArr.push(mapbox)
|
|
})
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initMapbox()
|
|
eventBus.on('fixit:switch-theme', ({ detail }) => {
|
|
if (!detail.isChanged)
|
|
return
|
|
const isDark = detail.isDark
|
|
mapboxArr.forEach((mapbox: any) => {
|
|
const $mapbox = mapbox.getContainer()
|
|
const { lightStyle, darkStyle } = JSON.parse($mapbox.dataset.options)
|
|
mapbox.setStyle(isDark ? darkStyle : lightStyle)
|
|
mapbox.addControl(new window.MapboxLanguage())
|
|
})
|
|
})
|
|
eventBus.on('fixit:content-decrypted', ({ detail }) => initMapbox(detail.target))
|
|
}, false)
|