Loading src/components/LGridLayer.vue +15 −39 Original line number Diff line number Diff line <script lang="ts"> import type L from "leaflet"; import { type PropType, defineComponent, h, inject, markRaw, nextTick, onMounted, onUnmounted, ref, render, } from "vue"; import { gridLayerProps, setupGridLayer } from "@src/functions/gridLayer"; import { CreateVueGridLayer, type VueGridLayerTileRenderer, gridLayerProps, setupGridLayer, } from "@src/functions/gridLayer"; import { AddLayerInjection, UseGlobalLeafletInjection, Loading @@ -28,13 +32,12 @@ export default defineComponent({ props: { ...gridLayerProps, childRender: { type: Function, type: Function as PropType<VueGridLayerTileRenderer>, required: true, }, }, setup(props, context) { const leafletObject = ref<L.GridLayer>(); const tileComponents = ref({}); // TODO: typing const root = ref(null); const ready = ref(false); Loading @@ -44,44 +47,21 @@ export default defineComponent({ const { options, methods } = setupGridLayer(props, leafletObject, context); onMounted(async () => { const { GridLayer, DomUtil }: typeof L = useGlobalLeaflet const { GridLayer, DomUtil, Util }: typeof L = useGlobalLeaflet ? WINDOW_OR_GLOBAL.L : await import("leaflet/dist/leaflet-src.esm"); methods.onUnload = (e) => { const key = leafletObject.value._tileCoordsToKey(e.coords); if (tileComponents[key]) { tileComponents[key].innerHTML = ""; tileComponents[key] = undefined; } }; methods.setTileComponent = () => { leafletObject.value.redraw(); }; const GLayer = GridLayer.extend({ createTile(coords) { const key = leafletObject.value._tileCoordsToKey(coords); tileComponents[key] = DomUtil.create("div"); let vNode = h( { setup: props.childRender, props: ["coords"] }, { coords } const GLayer = CreateVueGridLayer( GridLayer, DomUtil, Util, props.childRender ); render(vNode, tileComponents[key]); return tileComponents[key]; }, }); leafletObject.value = markRaw<L.GridLayer>(new GLayer(options)); const listeners = remapEvents(context.attrs); leafletObject.value.on(listeners); leafletObject.value.on("tileunload", methods.onUnload); propsBinder(methods, leafletObject.value, props); addLayer({ ...props, Loading @@ -92,10 +72,6 @@ export default defineComponent({ nextTick(() => context.emit("ready", leafletObject.value)); }); onUnmounted(() => { leafletObject.value.off("tileunload", methods.onUnload); }); return { root, ready, leafletObject }; }, render() { Loading src/functions/gridLayer.ts +45 −1 Original line number Diff line number Diff line import type L from "leaflet"; import type { PropType } from "vue"; import { type PropType, onUnmounted } from "vue"; import { type VNode, h, render } from "vue"; import { propsToLeafletOptions } from "@src/utils"; import { layerProps, setupLayer } from "./layer"; export type VueGridLayerTileRenderer = (props: { coords: L.Point; }) => () => VNode; export const gridLayerProps = { ...layerProps, opacity: { Loading Loading @@ -43,7 +48,46 @@ export const setupGridLayer = (props, leafletRef, context) => { const methods = { ...layerMethods, setTileComponent() { leafletRef.value?.redraw(); }, }; onUnmounted(() => { leafletRef.value.off(); }); return { options, methods }; }; export const CreateVueGridLayer = ( GridLayer: typeof L.GridLayer, DomUtil: typeof L.DomUtil, Util: typeof L.Util, childRenderer: VueGridLayerTileRenderer ) => GridLayer.extend({ initialize(options: L.GridLayerOptions) { this.tileComponents = {}; this.on("tileunload", this._unloadTile); Util.setOptions(this, options); }, createTile(coords: L.Point): HTMLElement { const key = this._tileCoordsToKey(coords); this.tileComponents[key] = DomUtil.create("div"); const vNode = h({ setup: childRenderer, props: ["coords"] }, { coords }); render(vNode, this.tileComponents[key]); return this.tileComponents[key]; }, _unloadTile(e: L.TileEvent): void { const key = this._tileCoordsToKey(e.coords); if (this.tileComponents[key]) { this.tileComponents[key].innerHTML = ""; this.tileComponents[key] = undefined; } }, }); Loading
src/components/LGridLayer.vue +15 −39 Original line number Diff line number Diff line <script lang="ts"> import type L from "leaflet"; import { type PropType, defineComponent, h, inject, markRaw, nextTick, onMounted, onUnmounted, ref, render, } from "vue"; import { gridLayerProps, setupGridLayer } from "@src/functions/gridLayer"; import { CreateVueGridLayer, type VueGridLayerTileRenderer, gridLayerProps, setupGridLayer, } from "@src/functions/gridLayer"; import { AddLayerInjection, UseGlobalLeafletInjection, Loading @@ -28,13 +32,12 @@ export default defineComponent({ props: { ...gridLayerProps, childRender: { type: Function, type: Function as PropType<VueGridLayerTileRenderer>, required: true, }, }, setup(props, context) { const leafletObject = ref<L.GridLayer>(); const tileComponents = ref({}); // TODO: typing const root = ref(null); const ready = ref(false); Loading @@ -44,44 +47,21 @@ export default defineComponent({ const { options, methods } = setupGridLayer(props, leafletObject, context); onMounted(async () => { const { GridLayer, DomUtil }: typeof L = useGlobalLeaflet const { GridLayer, DomUtil, Util }: typeof L = useGlobalLeaflet ? WINDOW_OR_GLOBAL.L : await import("leaflet/dist/leaflet-src.esm"); methods.onUnload = (e) => { const key = leafletObject.value._tileCoordsToKey(e.coords); if (tileComponents[key]) { tileComponents[key].innerHTML = ""; tileComponents[key] = undefined; } }; methods.setTileComponent = () => { leafletObject.value.redraw(); }; const GLayer = GridLayer.extend({ createTile(coords) { const key = leafletObject.value._tileCoordsToKey(coords); tileComponents[key] = DomUtil.create("div"); let vNode = h( { setup: props.childRender, props: ["coords"] }, { coords } const GLayer = CreateVueGridLayer( GridLayer, DomUtil, Util, props.childRender ); render(vNode, tileComponents[key]); return tileComponents[key]; }, }); leafletObject.value = markRaw<L.GridLayer>(new GLayer(options)); const listeners = remapEvents(context.attrs); leafletObject.value.on(listeners); leafletObject.value.on("tileunload", methods.onUnload); propsBinder(methods, leafletObject.value, props); addLayer({ ...props, Loading @@ -92,10 +72,6 @@ export default defineComponent({ nextTick(() => context.emit("ready", leafletObject.value)); }); onUnmounted(() => { leafletObject.value.off("tileunload", methods.onUnload); }); return { root, ready, leafletObject }; }, render() { Loading
src/functions/gridLayer.ts +45 −1 Original line number Diff line number Diff line import type L from "leaflet"; import type { PropType } from "vue"; import { type PropType, onUnmounted } from "vue"; import { type VNode, h, render } from "vue"; import { propsToLeafletOptions } from "@src/utils"; import { layerProps, setupLayer } from "./layer"; export type VueGridLayerTileRenderer = (props: { coords: L.Point; }) => () => VNode; export const gridLayerProps = { ...layerProps, opacity: { Loading Loading @@ -43,7 +48,46 @@ export const setupGridLayer = (props, leafletRef, context) => { const methods = { ...layerMethods, setTileComponent() { leafletRef.value?.redraw(); }, }; onUnmounted(() => { leafletRef.value.off(); }); return { options, methods }; }; export const CreateVueGridLayer = ( GridLayer: typeof L.GridLayer, DomUtil: typeof L.DomUtil, Util: typeof L.Util, childRenderer: VueGridLayerTileRenderer ) => GridLayer.extend({ initialize(options: L.GridLayerOptions) { this.tileComponents = {}; this.on("tileunload", this._unloadTile); Util.setOptions(this, options); }, createTile(coords: L.Point): HTMLElement { const key = this._tileCoordsToKey(coords); this.tileComponents[key] = DomUtil.create("div"); const vNode = h({ setup: childRenderer, props: ["coords"] }, { coords }); render(vNode, this.tileComponents[key]); return this.tileComponents[key]; }, _unloadTile(e: L.TileEvent): void { const key = this._tileCoordsToKey(e.coords); if (this.tileComponents[key]) { this.tileComponents[key].innerHTML = ""; this.tileComponents[key] = undefined; } }, });