map-offline/src/components/Map.vue

71 lines
1.9 KiB
Vue
Raw Normal View History

2023-07-26 16:55:19 +08:00
<script setup lang="ts">
2023-08-01 09:47:25 +08:00
import { ref, onMounted, provide, watch } from 'vue'
2023-07-26 16:55:19 +08:00
import 'leaflet/dist/leaflet.css'
2023-08-01 09:47:25 +08:00
import useMap from '../hook/useMap.ts'
2023-07-26 16:55:19 +08:00
import { useResizeObserver } from '@vueuse/core'
2023-08-01 09:47:25 +08:00
import { setOptions } from 'leaflet'
2023-07-26 16:55:19 +08:00
const mapContainer = ref()
2023-08-01 09:47:25 +08:00
const { map, tileLayers, props: mapProps } = useMap(mapContainer, { use: 'gaode', zoom: 13 });
// const config = defineModel<Object>()
2023-07-26 16:55:19 +08:00
const slotProps = ref({
contextmenu: {}
})
const mapFilter = ref('invert(1) grayscale(.2) saturate(0.8) brightness(1.8) opacity(1) hue-rotate(184deg) sepia(17%)'); // 地图滤镜
provide('map', map) // 注入的内容 mapChild 下
onMounted(() => {
2023-08-01 09:47:25 +08:00
map.value?.addEventListener("contextmenu", (e) => {
2023-07-26 16:55:19 +08:00
slotProps.value.contextmenu = e
})
})
2023-08-01 09:47:25 +08:00
watch({ center: mapProps.value.center }, ({ center }) => center && map.value?.flyTo(center))
watch({ max: mapProps.value.maxZoom || 0 }, ({ max }) => map.value?.setMaxZoom(max))
watch({ min: mapProps.value.minZoom || 0 }, ({ min }) => map.value?.setMaxZoom(min))
watch({ url: mapProps.value.urlTemplate }, ({ url }) => url && tileLayers.value[0].setUrl(url))
watch({ zoomSnap: mapProps.value.zoomSnap }, ({ zoomSnap }) => map.value && (map.value.options.zoomSnap = zoomSnap))
2023-07-26 16:55:19 +08:00
function changeMapFilter(filterInfo: Record<'blur' |
'brightness' |
'contrast' |
'drop-shadow' |
'grayscale' |
'hue-rotate' |
'invert' |
'opacity' |
'saturate' |
'sepia', string | number>) {
mapFilter.value = Object.entries(filterInfo).map(([key, value]) => `${key}(${value})`).join(' ')
}
useResizeObserver(mapContainer, () => map.value?.invalidateSize(true))
2023-08-01 09:47:25 +08:00
defineExpose({ changeMapFilter, setOptions })
2023-07-26 16:55:19 +08:00
</script>
<template>
<div class="mapContainer" ref="mapContainer" :style="{ '--mapFilter': mapFilter }">
<slot v-if="map" v-bind="slotProps"></slot>
</div>
</template>
<style lang="scss">
.mapContainer {
grid-area: map;
}
body.body--dark {
.mapFilter {
filter: var(--mapFilter);
}
}
</style>