import { DC, EntityShape } from "@/deconstruction"; import { computed, onUnmounted, ref, Ref, toRaw, watch, watchEffect, } from "vue"; import { DrawItem } from "../components"; import { useStore } from "../store"; import { installGlobalVar, useStage } from "./use-global-vars"; import { Layer } from "konva/lib/Layer"; import { useMouseShapeStatus } from "./use-mouse-status"; // const useRefreshCount = installGlobalVar(() => ref(0)); // const useRefresh = () => { // useRefreshCount // } export const useTempLayer = () => { const stage = useStage(); return computed(() => stage.value?.getNode().find("#temp")[0]); }; export const useFormalLayer = () => { const stage = useStage(); return computed(() => stage.value?.getNode().find("#formal")[0]); }; export const useHelperLayer = () => { const stage = useStage(); return computed(() => stage.value?.getNode().find("#helper")[0]); }; export const useMigrateLayer = (shape: Ref | undefined>) => { const formal = useFormalLayer(); const zIndexs = useZIndexsManage(); let rawLayer: Layer; let toLayer: Layer; const recovery = () => { const $shape = shape.value?.getNode(); if (rawLayer && $shape) { $shape.remove(); rawLayer.add($shape); if (import.meta.env.DEV) { setTimeout(() => { console.log( `recovery raw:${rawLayer.id()} ${rawLayer.children.length} to:${toLayer.id()} ${toLayer.children.length}`, ); }) } if (toRaw(formal.value) === toRaw(rawLayer) && zIndexs.get($shape)) { zIndexs.refresh(); } } }; const migrate = (to: Layer) => { if (!shape.value) throw "shape不存在"; const $shape = shape.value.getNode(); rawLayer = $shape.getLayer()!; toLayer = to; $shape.remove(); to.add($shape); if (import.meta.env.DEV) { console.log( `migrate raw:${rawLayer.id()} ${rawLayer.children.length} to:${toLayer.id()} ${toLayer.children.length}`, ); } }; return [migrate, recovery] as const; }; export const useMouseMigrateTempLayer = ( shape: Ref | undefined> ) => { const status = useMouseShapeStatus(shape); const tempLayer = useTempLayer(); const [migrate, recovery] = useMigrateLayer(shape); const isMigrate = computed(() => status.value.active || status.value.hover); // 鼠标状态改变则迁移图层 watch( isMigrate, (isMigrate, _, onCleanup) => { if (isMigrate && tempLayer.value) { migrate(tempLayer.value); onCleanup(recovery); } }, { flush: 'sync' } ); }; const useCurrentStaticZIndex = installGlobalVar(() => ref(0)); export const useStaticZIndex = (refNum = 1) => { const current = useCurrentStaticZIndex(); let isDestory = false; const destroy = () => { if (!isDestory) { current.value -= refNum; isDestory = true; } }; onUnmounted(destroy); const result = new Array(refNum).fill(0).map((_, i) => current.value + i + 1); current.value += refNum; return result; }; const useZIndexsManage = installGlobalVar(() => { const store = useStore(); const map = ref(new Map()); const current = useCurrentStaticZIndex(); const formal = useFormalLayer(); const sortItems = computed(() => { const items = Array.from(map.value.values()); return store.getItemsZIndex(items); }) const setZIndexs = () => { const shapes = Array.from(map.value.keys()); const raws = Array.from(map.value.values()); let start = current.value; sortItems.value.forEach((item) => { const rawNdx = raws.findIndex((raw) => raw === item); const shape = shapes[rawNdx]; const layer = shape.getLayer(); if (toRaw(layer) !== toRaw(formal.value)) return -1; shape.zIndex(start++); }); }; watch(sortItems, setZIndexs) return { set(shape: EntityShape, item: DrawItem) { map.value.set(shape, item); }, del(shape: EntityShape) { map.value.delete(shape); }, get(shape: EntityShape) { return map.value.get(shape); }, refresh: setZIndexs, }; }); export const useZIndex = ( shape: Ref | undefined>, atData: Ref ) => { const zIndexs = useZIndexsManage(); watch(shape, (shape, _, onCleanup) => { const $shape = shape?.getNode(); if ($shape) { watchEffect(() => { zIndexs.set($shape, atData.value); }); onCleanup(() => { zIndexs.del($shape); }); } }); };