123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- <template>
- <v-group ref="grid" v-if="hLines && rect" :config="{ listening: false }">
- <template v-for="item in hLines">
- <v-line
- v-for="l in item.children"
- :config="{
- points: [rect[0].x, l, rect[1].x, l],
- ...style,
- strokeWidth: style.strokeWidth * 0.33,
- }"
- />
- </template>
- <template v-for="item in vLines">
- <v-line
- v-for="l in item.children"
- :config="{
- points: [l, rect[0].y, l, rect[1].y],
- ...style,
- strokeWidth: style.strokeWidth * 0.33,
- }"
- />
- </template>
- <v-line
- v-for="item in hLines"
- :config="{ points: [rect[0].x, item.dividing, rect[1].x, item.dividing], ...style }"
- />
- <v-line
- v-for="item in vLines"
- :config="{ points: [item.dividing, rect[0].y, item.dividing, rect[1].y], ...style }"
- />
- </v-group>
- </template>
- <script lang="ts" setup>
- import { computed, ref, watch } from "vue";
- import { useResize } from "../hook/use-event";
- import { useShapeStaticZindex } from "../hook/use-layer";
- import {
- useViewerInvertTransform,
- useViewerTransform,
- useViewerTransformConfig,
- } from "../hook/use-viewer";
- import { DC } from "@/deconstruction";
- import { Rect } from "konva/lib/shapes/Rect";
- import { lineLen } from "@/utils/math";
- import { debounce } from "@/utils/shared";
- const grid = ref<DC<Rect>>();
- useShapeStaticZindex(grid);
- const style = {
- stroke: "#ccc",
- strokeWidth: 3,
- opacity: 0.4,
- strokeScaleEnabled: false,
- };
- const pixelSize = useResize();
- const viewerInvertTransform = useViewerInvertTransform();
- // 真实rect
- const rect = computed(() => {
- if (!pixelSize.value) return null;
- const start = viewerInvertTransform.value.point({ x: 0, y: 0 });
- const end = viewerInvertTransform.value.point({
- x: pixelSize.value.width,
- y: pixelSize.value.height,
- });
- return [start, end];
- });
- // 看大格子的像素,100倍数
- const offsetUnit = 100;
- const minScalePixel = offsetUnit / 2;
- const viewerTransform = useViewerTransform();
- const viewerTransformConfig = useViewerTransformConfig();
- const offset = ref(offsetUnit);
- watch(
- () => `${viewerTransformConfig.value.scaleX},${viewerTransformConfig.value.scaleY}`,
- () => {
- offset.value = offsetUnit;
- const start = viewerTransform.value.point({ x: 0, y: 0 });
- let i = 0;
- while (true) {
- const end = viewerTransform.value.point({ x: offset.value, y: 0 });
- if (lineLen(start, end) >= minScalePixel) {
- break;
- }
- offset.value *= 2;
- i++;
- if (i > 200) {
- break;
- }
- }
- }
- );
- const getFinal = (val: number, isTop: boolean) => {
- let t = val / offset.value;
- t = isTop ? Math.floor(t) : Math.ceil(t);
- return offset.value * t;
- };
- type DireLine = {
- dividing: number;
- children: number[];
- };
- const getLines = (min: number, max: number) => {
- const isReverse = min > max;
- const start = getFinal(min, !isReverse);
- const end = getFinal(max, isReverse);
- const diff = isReverse ? -offset.value : offset.value;
- let current = start;
- const lines: DireLine[] = [];
- while (diff > 0 ? current <= end : current >= end) {
- const item: DireLine = {
- dividing: current,
- children: [],
- };
- const cOffset = ((diff > 0 ? -1 : 1) * offset.value) / 5;
- for (let i = 1; i < 5; i++) {
- item.children.push(current + cOffset * i);
- }
- lines.push(item);
- current += diff;
- }
- return lines;
- };
- const hLines = ref<DireLine[]>([]);
- const vLines = ref<DireLine[]>([]);
- watch(
- rect,
- debounce(() => {
- if (!rect.value) {
- hLines.value = [];
- vLines.value = [];
- } else {
- hLines.value = getLines(rect.value[0].y, rect.value[1].y);
- vLines.value = getLines(rect.value[0].x, rect.value[1].x);
- }
- }, 16),
- { immediate: true }
- );
- </script>
|