123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- <template>
- <v-rect
- :config="{ ...data, opacity: 1, zIndex: undefined, strokeScaleEnable: true }"
- ref="shape"
- />
- </template>
- <script lang="ts" setup>
- import { defaultStyle, GroupData } from "./index.ts";
- import { computed, nextTick, onUnmounted, ref, watch } from "vue";
- import { DC, EntityShape } from "@/deconstruction.js";
- import { Rect, RectConfig } from "konva/lib/shapes/Rect";
- import { useViewerInvertTransform } from "@/core/hook/use-viewer.ts";
- import { useStage } from "@/core/hook/use-global-vars.ts";
- import { useOnComponentBoundChange } from "@/core/hook/use-component.ts";
- import { debounce } from "@/utils/shared.ts";
- const props = defineProps<{
- data: GroupData;
- addMode?: boolean;
- autoUpdate?: boolean;
- }>();
- const shape = ref<DC<Rect>>();
- const data = computed(() => ({ ...defaultStyle, ...props.data }));
- const stage = useStage();
- const getGroupShapes = () => {
- const $stage = stage.value?.getNode();
- if (!$stage) return;
- const shapes: EntityShape[] = [];
- for (const id of data.value.ids) {
- const $shape = $stage!.findOne(`#${id}`)!;
- if (!$shape || $shape.attrs.disableGroupOper) continue;
- shapes.push($shape as EntityShape);
- }
- return shapes;
- };
- const invMat = useViewerInvertTransform();
- const updateBound = () => {
- const shapes = $shapes.value;
- if (!shapes?.length) {
- console.error("!shapes");
- return;
- }
- let lx = Number.MAX_VALUE;
- let ly = Number.MAX_VALUE;
- let rx = Number.MIN_VALUE;
- let ry = Number.MIN_VALUE;
- for (const shape of shapes) {
- if (!shape) continue;
- const rect = shape.getClientRect();
- if (rect.x < lx) {
- lx = rect.x;
- }
- if (rect.y < ly) {
- ly = rect.y;
- }
- if (rect.x + rect.width > rx) {
- rx = rect.x + rect.width;
- }
- if (rect.y + rect.height > ry) {
- ry = rect.y + rect.height;
- }
- }
- const pixelStart = invMat.value.point({ x: lx, y: ly });
- const pixelEnd = invMat.value.point({ x: rx, y: ry });
- lx = pixelStart.x;
- ly = pixelStart.y;
- rx = pixelEnd.x;
- ry = pixelEnd.y;
- const config: RectConfig = {
- x: lx,
- y: ly,
- width: rx - lx,
- height: ry - ly,
- rotation: 0,
- scaleX: 1,
- scaleY: 1,
- };
- const $shape = shape.value?.getNode() as any;
- if ($shape) {
- for (const key in config) {
- $shape[key](config[key]);
- }
- nextTick(() => $shape.fire("bound-change"));
- }
- };
- watch(
- () => data.value.ids.length,
- () => nextTick(updateBound),
- { immediate: true }
- );
- const { on } = useOnComponentBoundChange();
- const $shapes = computed(getGroupShapes);
- const syncUpdateBound = debounce(updateBound, 0);
- watch(
- () => {
- return (
- data.value.ids.join(",") +
- (props.autoUpdate ? "1" : "0") +
- (data.value.listening ? "1" : "0") +
- (stage.value ? "1" : "0")
- );
- },
- (_a, _b, onCleanup) => {
- if (props.autoUpdate) {
- onCleanup(
- on(
- $shapes,
- () => {
- props.autoUpdate && syncUpdateBound();
- },
- false
- )
- );
- }
- },
- { immediate: true }
- );
- onUnmounted(() => console.error("des temp-group"));
- defineExpose({
- get shape() {
- return shape.value;
- },
- updateBound,
- getGroupShapes,
- });
- </script>
|