import { Viewer } from "../viewer.ts"; import { computed, ref, watch, watchEffect } from "vue"; import { dragListener, scaleListener } from "../../utils/event.ts"; import { globalWatch, installGlobalVar, useStage, } from "./use-global-vars.ts"; import { useCan } from './use-status' import { mergeFuns } from "../../utils/shared.ts"; import { Transform } from "konva/lib/Util"; import { lineLen } from "@/utils/math.ts"; import { useResize } from "./use-event.ts"; export const useViewer = installGlobalVar(() => { const stage = useStage(); const viewer = new Viewer(); const can = useCan() const size = useResize() const transform = ref(new Transform()); const init = (dom: HTMLDivElement) => { const onDestroy = mergeFuns( dragListener(dom, { move: ({ end, prev }) => { if (can.viewMode) { viewer.movePixel({ x: end.x - prev.x, y: end.y - prev.y }); } }, notPrevent: true, }), scaleListener(dom, (info) => { if (can.viewMode) { viewer.scalePixel(info.center, info.scale); } }), watchEffect(() => { size.value && viewer.setSize(size.value) }) ) viewer.bus.on("transformChange", (newTransform) => { transform.value = newTransform; }); transform.value = viewer.transform; return onDestroy; }; return { var: { transform: transform, viewer, }, onDestroy: globalWatch( () => can.viewMouseReact, (can, _, onCleanup) => { if (can) { const dom = stage.value!.getNode().container(); onCleanup(init(dom)); } }, { immediate: true } ), }; }, Symbol("viewer")); export const useViewerTransform = installGlobalVar(() => { const viewer = useViewer(); return viewer.transform; }, Symbol("viewTransform")); export const useViewerTransformConfig = () => { const transform = useViewerTransform(); return computed(() => transform.value.decompose()); }; export const useViewerInvertTransform = () => { const transform = useViewerTransform(); return computed(() => transform.value.copy().invert()); }; export const useViewerInvertTransformConfig = () => { const transform = useViewerInvertTransform(); return computed(() => transform.value.decompose()); }; export const useUnitTransform = installGlobalVar(() => { const transform = useViewerTransform(); const invTransform = useViewerInvertTransform(); return { getPixel(real: number) { return lineLen( invTransform.value.point({ x: real, y: 0 }), invTransform.value.point({ x: 0, y: 0 }) ); }, getReal(pixel: number) { return lineLen( transform.value.point({ x: pixel, y: 0 }), transform.value.point({ x: 0, y: 0 }) ); }, }; }, Symbol("unitTransform")); export const useCacheUnitTransform = installGlobalVar(() => { const unitTransform = useUnitTransform(); const transform = useViewerTransform(); const invTransform = useViewerInvertTransform(); let pixelCache: Record = {}; let realCache: Record = {}; watch(transform, () => { pixelCache = {}; }); watch(invTransform, () => { realCache = {}; }); return { getPixel(real: number) { if (real in pixelCache) { return pixelCache[real]; } else { return (pixelCache[real] = unitTransform.getPixel(real)); } }, getReal(pixel: number) { if (pixel in realCache) { return realCache[pixel]; } else { return (pixelCache[pixel] = unitTransform.getReal(pixel)); } }, }; }, Symbol("cacheUnitTransform"));