|
@@ -7,9 +7,9 @@ import {
|
|
useStage,
|
|
useStage,
|
|
} from "./use-global-vars";
|
|
} from "./use-global-vars";
|
|
import {
|
|
import {
|
|
- useGetFormalChildren,
|
|
|
|
useFormalLayer,
|
|
useFormalLayer,
|
|
useHelperLayer,
|
|
useHelperLayer,
|
|
|
|
+ useGetFormalChildren,
|
|
} from "./use-layer";
|
|
} from "./use-layer";
|
|
import { themeColor } from "@/constant";
|
|
import { themeColor } from "@/constant";
|
|
import { dragListener } from "@/utils/event";
|
|
import { dragListener } from "@/utils/event";
|
|
@@ -20,6 +20,7 @@ import {
|
|
markRaw,
|
|
markRaw,
|
|
nextTick,
|
|
nextTick,
|
|
reactive,
|
|
reactive,
|
|
|
|
+ Ref,
|
|
ref,
|
|
ref,
|
|
toRaw,
|
|
toRaw,
|
|
watch,
|
|
watch,
|
|
@@ -27,91 +28,35 @@ import {
|
|
} from "vue";
|
|
} from "vue";
|
|
import { EntityShape } from "@/deconstruction";
|
|
import { EntityShape } from "@/deconstruction";
|
|
import { Util } from "konva/lib/Util";
|
|
import { Util } from "konva/lib/Util";
|
|
-import { useViewerInvertTransform, useViewerInvertTransformConfig } from "./use-viewer";
|
|
|
|
|
|
+import {
|
|
|
|
+ useViewerInvertTransform,
|
|
|
|
+ useViewerInvertTransformConfig,
|
|
|
|
+} from "./use-viewer";
|
|
import { debounce, diffArrayChange, mergeFuns, onlyId } from "@/utils/shared";
|
|
import { debounce, diffArrayChange, mergeFuns, onlyId } from "@/utils/shared";
|
|
import { IRect } from "konva/lib/types";
|
|
import { IRect } from "konva/lib/types";
|
|
import { useMouseShapesStatus } from "./use-mouse-status";
|
|
import { useMouseShapesStatus } from "./use-mouse-status";
|
|
import Icon from "../components/icon/temp-icon.vue";
|
|
import Icon from "../components/icon/temp-icon.vue";
|
|
import { Group } from "konva/lib/Group";
|
|
import { Group } from "konva/lib/Group";
|
|
-import { Component as GroupComp, GroupData } from "../components/group/";
|
|
|
|
-import { DrawStore, useStore } from "../store";
|
|
|
|
-import { DrawItem } from "../components";
|
|
|
|
-import { Stage } from "konva/lib/Stage";
|
|
|
|
-import { useOnComponentBoundChange } from "./use-component";
|
|
|
|
|
|
+import { Component as GroupComp, GroupData } from "../components/group";
|
|
|
|
+import { useStore } from "../store";
|
|
|
|
+import { useGetShapeBelong, useOnComponentBoundChange } from "./use-component";
|
|
import { useHistory } from "./use-history";
|
|
import { useHistory } from "./use-history";
|
|
import { isRectContained } from "@/utils/math";
|
|
import { isRectContained } from "@/utils/math";
|
|
import { useTransformer } from "./use-transformer";
|
|
import { useTransformer } from "./use-transformer";
|
|
-
|
|
|
|
-const normalSelectIds = (
|
|
|
|
- store: DrawStore,
|
|
|
|
- ids: string[],
|
|
|
|
- needChildren = false
|
|
|
|
-) => {
|
|
|
|
- if (!store.typeItems.group) return ids;
|
|
|
|
-
|
|
|
|
- const gChildrenIds = store.typeItems.group.map((item) => item.ids);
|
|
|
|
- const findNdx = (id: string) =>
|
|
|
|
- gChildrenIds.findIndex((cIds) => cIds.includes(id));
|
|
|
|
- if (!needChildren) {
|
|
|
|
- return ids.filter((id) => !~findNdx(id));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const groupIds = store.typeItems.group.map((item) => item.id);
|
|
|
|
- const nIds: string[] = [];
|
|
|
|
- for (let i = 0; i < ids.length; i++) {
|
|
|
|
- let ndx = findNdx(ids[i]);
|
|
|
|
- ~ndx || (ndx = groupIds.indexOf(ids[i]));
|
|
|
|
-
|
|
|
|
- if (!~ndx) {
|
|
|
|
- nIds.push(ids[i]);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const group = store.typeItems.group[ndx];
|
|
|
|
- const addIds = [group.id, ...group.ids].filter(
|
|
|
|
- (aid) => !nIds.includes(aid)
|
|
|
|
- );
|
|
|
|
- nIds.push(...addIds);
|
|
|
|
- }
|
|
|
|
- return nIds;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-export const normalSelectShapes = (
|
|
|
|
- stage: Stage,
|
|
|
|
- store: DrawStore,
|
|
|
|
- shapes: EntityShape[],
|
|
|
|
- needChildren = false
|
|
|
|
-) => {
|
|
|
|
- let ids: string[] = [];
|
|
|
|
- for (let i = 0; i < shapes.length; i++) {
|
|
|
|
- const shape = shapes[i];
|
|
|
|
- const id = shape.id();
|
|
|
|
- id && ids.push(id);
|
|
|
|
- }
|
|
|
|
- ids = normalSelectIds(store, ids, needChildren);
|
|
|
|
- return ids.map((id) => stage.findOne(`#${id}`)!) as EntityShape[];
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-export const normalSelectItems = (
|
|
|
|
- store: DrawStore,
|
|
|
|
- items: DrawItem[],
|
|
|
|
- needChildren = false
|
|
|
|
-) => {
|
|
|
|
- return normalSelectIds(
|
|
|
|
- store,
|
|
|
|
- items.map((item) => item.id),
|
|
|
|
- needChildren
|
|
|
|
- ).map((id) => store.getItemById(id)!);
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-export const useExcludeSelection = installGlobalVar(() => ref<string[]>([]))
|
|
|
|
-
|
|
|
|
|
|
+import { IconData } from "../components/icon";
|
|
|
|
+import { usePause } from "./use-pause";
|
|
|
|
+import mitt, { Emitter } from "mitt";
|
|
|
|
+import { components, ShapeType, shapeTypes } from "../components";
|
|
|
|
+import { getFlatChildren } from "@/utils/shape";
|
|
|
|
+
|
|
|
|
+export const useExcludeSelection = installGlobalVar(() => ref<string[]>([]));
|
|
|
|
+// 多选不包含分组, 只包含选中者
|
|
export const useSelection = installGlobalVar(() => {
|
|
export const useSelection = installGlobalVar(() => {
|
|
const layer = useHelperLayer();
|
|
const layer = useHelperLayer();
|
|
- const eSelection = useExcludeSelection()
|
|
|
|
|
|
+ const eSelection = useExcludeSelection();
|
|
const getChildren = useGetFormalChildren();
|
|
const getChildren = useGetFormalChildren();
|
|
const box = new Rect({
|
|
const box = new Rect({
|
|
- stroke: themeColor,
|
|
|
|
|
|
+ stroke: themeColor,
|
|
strokeWidth: 1,
|
|
strokeWidth: 1,
|
|
fill: "#fff",
|
|
fill: "#fff",
|
|
listening: false,
|
|
listening: false,
|
|
@@ -121,29 +66,36 @@ export const useSelection = installGlobalVar(() => {
|
|
const operMode = useOperMode();
|
|
const operMode = useOperMode();
|
|
const selections = ref<EntityShape[]>();
|
|
const selections = ref<EntityShape[]>();
|
|
const transformer = useTransformer();
|
|
const transformer = useTransformer();
|
|
|
|
+ const getShapeSelectionManage = useGetShapeSelectionManage();
|
|
|
|
|
|
- let shapeBoxs: IRect[] = [];
|
|
|
|
- let shapes: EntityShape[] = [];
|
|
|
|
|
|
+ let itemShapeBoxs: IRect[][] = [];
|
|
|
|
+ let itemShapes: EntityShape[][] = [];
|
|
|
|
|
|
const updateSelections = () => {
|
|
const updateSelections = () => {
|
|
const boxRect = box.getClientRect();
|
|
const boxRect = box.getClientRect();
|
|
selections.value = [];
|
|
selections.value = [];
|
|
-
|
|
|
|
- for (let i = 0; i < shapeBoxs.length; i++) {
|
|
|
|
- if (
|
|
|
|
-
|
|
|
|
- Util.haveIntersection(boxRect, shapeBoxs[i]) &&
|
|
|
|
- !isRectContained(shapeBoxs[i], boxRect) &&
|
|
|
|
- shapes[i] !== toRaw(transformer)
|
|
|
|
- ) {
|
|
|
|
- if (!selections.value.includes(shapes[i])) {
|
|
|
|
- selections.value.push(shapes[i]);
|
|
|
|
|
|
+ for (let i = 0; i < itemShapeBoxs.length; i++) {
|
|
|
|
+ for (let j = 0; j < itemShapeBoxs[i].length; j++) {
|
|
|
|
+ const shape = itemShapes[i][j];
|
|
|
|
+ const box = itemShapeBoxs[i][j];
|
|
|
|
+ const itemSelects: EntityShape[] = [];
|
|
|
|
+ if (
|
|
|
|
+ Util.haveIntersection(boxRect, box) &&
|
|
|
|
+ !isRectContained(box, boxRect)
|
|
|
|
+ ) {
|
|
|
|
+ if (!selections.value.includes(shape)) {
|
|
|
|
+ selections.value.push(shape);
|
|
|
|
+ itemSelects.push(shape);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ const store = useStore();
|
|
const init = (dom: HTMLDivElement, layer: Layer) => {
|
|
const init = (dom: HTMLDivElement, layer: Layer) => {
|
|
|
|
+ store.bus.on("addItemAfter", updateInitData);
|
|
|
|
+ store.bus.on('dataChangeAfter', updateInitData);
|
|
const stopListener = dragListener(dom, {
|
|
const stopListener = dragListener(dom, {
|
|
down(pos) {
|
|
down(pos) {
|
|
layer.add(box);
|
|
layer.add(box);
|
|
@@ -163,14 +115,25 @@ export const useSelection = installGlobalVar(() => {
|
|
},
|
|
},
|
|
});
|
|
});
|
|
return () => {
|
|
return () => {
|
|
|
|
+ store.bus.off("addItemAfter", updateInitData);
|
|
|
|
+ store.bus.off('dataChangeAfter', updateInitData);
|
|
stopListener();
|
|
stopListener();
|
|
box.remove();
|
|
box.remove();
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
const updateInitData = () => {
|
|
const updateInitData = () => {
|
|
- shapes = getChildren().filter(shape => !eSelection.value.includes(shape.id()));
|
|
|
|
- shapeBoxs = shapes.map((shape) => shape.getClientRect());
|
|
|
|
|
|
+ itemShapes = getChildren().map((item) =>
|
|
|
|
+ getFlatChildren(item).filter(
|
|
|
|
+ (shape) =>
|
|
|
|
+ !eSelection.value.includes(shape.id()) &&
|
|
|
|
+ shape !== toRaw(transformer) &&
|
|
|
|
+ getShapeSelectionManage(shape)?.canSelect(shape)
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+ itemShapeBoxs = itemShapes.map((shapes) =>
|
|
|
|
+ shapes.map((shape) => shape.getClientRect())
|
|
|
|
+ );
|
|
};
|
|
};
|
|
|
|
|
|
const stopWatch = globalWatch(
|
|
const stopWatch = globalWatch(
|
|
@@ -185,11 +148,17 @@ export const useSelection = installGlobalVar(() => {
|
|
|
|
|
|
return {
|
|
return {
|
|
onDestroy: stopWatch,
|
|
onDestroy: stopWatch,
|
|
- var: {selections, box},
|
|
|
|
|
|
+ var: { selections, box },
|
|
};
|
|
};
|
|
});
|
|
});
|
|
|
|
|
|
-export const useSelectionShowIcons = installGlobalVar(() => {
|
|
|
|
|
|
+type ShapeIconArgs = Partial<
|
|
|
|
+ Pick<IconData, "width" | "height" | "url" | "fill" | "stroke">
|
|
|
|
+>;
|
|
|
|
+export const useShapesIcon = (
|
|
|
|
+ shapes: Ref<EntityShape[] | undefined>,
|
|
|
|
+ args: ShapeIconArgs = {}
|
|
|
|
+) => {
|
|
const mParts = useMountParts();
|
|
const mParts = useMountParts();
|
|
const { on } = useOnComponentBoundChange();
|
|
const { on } = useOnComponentBoundChange();
|
|
const iconProps = {
|
|
const iconProps = {
|
|
@@ -198,13 +167,10 @@ export const useSelectionShowIcons = installGlobalVar(() => {
|
|
url: "./icons/state_s.svg",
|
|
url: "./icons/state_s.svg",
|
|
fill: themeColor,
|
|
fill: themeColor,
|
|
stroke: "#fff",
|
|
stroke: "#fff",
|
|
|
|
+ ...args,
|
|
listening: false,
|
|
listening: false,
|
|
};
|
|
};
|
|
- const invConfig = useViewerInvertTransformConfig()
|
|
|
|
- const status = useMouseShapesStatus();
|
|
|
|
- const getChildren = useGetFormalChildren()
|
|
|
|
-
|
|
|
|
- const store = useStore();
|
|
|
|
|
|
+ const invConfig = useViewerInvertTransformConfig();
|
|
const invMat = useViewerInvertTransform();
|
|
const invMat = useViewerInvertTransform();
|
|
const getShapeMat = (shape: EntityShape) => {
|
|
const getShapeMat = (shape: EntityShape) => {
|
|
const rect = shape.getClientRect();
|
|
const rect = shape.getClientRect();
|
|
@@ -214,22 +180,28 @@ export const useSelectionShowIcons = installGlobalVar(() => {
|
|
});
|
|
});
|
|
return [1, 0, 0, 1, center.x, center.y];
|
|
return [1, 0, 0, 1, center.x, center.y];
|
|
};
|
|
};
|
|
- const shapes = computed(() => {
|
|
|
|
- const child = getChildren()
|
|
|
|
- return status.selects.filter((shape) => store.getType(shape.id()) !== "group" && child.includes(shape))
|
|
|
|
- });
|
|
|
|
const unMountMap = new WeakMap<EntityShape, () => void>();
|
|
const unMountMap = new WeakMap<EntityShape, () => void>();
|
|
- watch(shapes, (shapes, oldShapes) => {
|
|
|
|
- const { added, deleted } = diffArrayChange(shapes, oldShapes);
|
|
|
|
|
|
+
|
|
|
|
+ const pause = usePause();
|
|
|
|
+ const stop = watch([shapes, () => pause.isPause], ([shapes], [oldShapes]) => {
|
|
|
|
+ if (pause.isPause) {
|
|
|
|
+ shapes = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const { added, deleted } = diffArrayChange(shapes || [], oldShapes || []);
|
|
for (const addShape of added) {
|
|
for (const addShape of added) {
|
|
const mat = ref(getShapeMat(addShape));
|
|
const mat = ref(getShapeMat(addShape));
|
|
- const data = reactive({ ...iconProps, mat: mat })
|
|
|
|
|
|
+ const data = reactive({ ...iconProps, mat: mat });
|
|
const unHooks = [
|
|
const unHooks = [
|
|
on(addShape, () => (mat.value = getShapeMat(addShape))),
|
|
on(addShape, () => (mat.value = getShapeMat(addShape))),
|
|
- watch(invConfig, () => {
|
|
|
|
- data.width = invConfig.value.scaleX * iconProps.width
|
|
|
|
- data.height = invConfig.value.scaleY * iconProps.height
|
|
|
|
- }, {immediate: true}),
|
|
|
|
|
|
+ watch(
|
|
|
|
+ invConfig,
|
|
|
|
+ () => {
|
|
|
|
+ data.width = invConfig.value.scaleX * iconProps.width;
|
|
|
|
+ data.height = invConfig.value.scaleY * iconProps.height;
|
|
|
|
+ },
|
|
|
|
+ { immediate: true }
|
|
|
|
+ ),
|
|
mParts.add({
|
|
mParts.add({
|
|
comp: markRaw(Icon),
|
|
comp: markRaw(Icon),
|
|
props: { data },
|
|
props: { data },
|
|
@@ -242,134 +214,120 @@ export const useSelectionShowIcons = installGlobalVar(() => {
|
|
fn && fn();
|
|
fn && fn();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
-});
|
|
|
|
-
|
|
|
|
-const useWatchSelection = () => {
|
|
|
|
- const status = useMouseShapesStatus();
|
|
|
|
- const addShapes = (allShapes: Set<EntityShape>, iShapes: EntityShape[]) => {
|
|
|
|
- iShapes.forEach((shape) => allShapes.add(toRaw(shape)));
|
|
|
|
- return allShapes;
|
|
|
|
- };
|
|
|
|
- const delShapes = (allShapes: Set<EntityShape>, dShapes: EntityShape[]) => {
|
|
|
|
- dShapes.forEach((item) => allShapes.delete(toRaw(item)));
|
|
|
|
- return allShapes;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // 分组管理
|
|
|
|
- const watchSelection = () =>
|
|
|
|
- watch(
|
|
|
|
- () => status.selects,
|
|
|
|
- (shapes) => {
|
|
|
|
- const fShapes = Array.from(new Set(shapes));
|
|
|
|
- const { added, deleted } = diffArrayChange(shapes, fShapes);
|
|
|
|
- if (added.length || deleted.length) {
|
|
|
|
- status.selects = fShapes;
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- { flush: "post" }
|
|
|
|
- );
|
|
|
|
|
|
+ return [stop, pause];
|
|
|
|
+};
|
|
|
|
|
|
- return {
|
|
|
|
- addShapes,
|
|
|
|
- delShapes,
|
|
|
|
- watchSelection,
|
|
|
|
|
|
+export type SelectionManageBus = Emitter<Record<"del" | "update", EntityShape>>;
|
|
|
|
+export type SelectionManage = {
|
|
|
|
+ canSelect: (shape: EntityShape, selects?: EntityShape[]) => boolean;
|
|
|
|
+ listener: (shape: EntityShape) => {
|
|
|
|
+ stop: () => void;
|
|
|
|
+ bus: SelectionManageBus;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
+export type UseGetSelectionManage = () => SelectionManage;
|
|
|
|
|
|
-const useWatchSelectionGroup = () => {
|
|
|
|
- const stage = useStage();
|
|
|
|
|
|
+export const useStoreSelectionManage = installGlobalVar((): SelectionManage => {
|
|
const store = useStore();
|
|
const store = useStore();
|
|
- const status = useMouseShapesStatus();
|
|
|
|
- const addShapes = (allShapes: Set<EntityShape>, iShapes: EntityShape[]) => {
|
|
|
|
- const shapes = normalSelectShapes(
|
|
|
|
- stage.value!.getNode(),
|
|
|
|
- store,
|
|
|
|
- iShapes,
|
|
|
|
- true
|
|
|
|
- );
|
|
|
|
- shapes.forEach((shape) => allShapes.add(shape));
|
|
|
|
- return allShapes;
|
|
|
|
- };
|
|
|
|
- const delShapes = (allShapes: Set<EntityShape>, dShapes: EntityShape[]) => {
|
|
|
|
- const shapes = normalSelectShapes(
|
|
|
|
- stage.value!.getNode(),
|
|
|
|
- store,
|
|
|
|
- dShapes,
|
|
|
|
- true
|
|
|
|
- );
|
|
|
|
- shapes.forEach((item) => allShapes.delete(item));
|
|
|
|
- return allShapes;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // 分组管理
|
|
|
|
- const watchSelection = () =>
|
|
|
|
- watch(
|
|
|
|
- () => status.selects,
|
|
|
|
- (shapes, oldShapes) => {
|
|
|
|
- const { added, deleted } = diffArrayChange(shapes, oldShapes);
|
|
|
|
- const filterShapes = new Set(shapes);
|
|
|
|
- added.length && addShapes(filterShapes, added);
|
|
|
|
- deleted.length && delShapes(filterShapes, deleted);
|
|
|
|
|
|
+ const { on } = useOnComponentBoundChange();
|
|
|
|
|
|
- if (added.length || deleted.length) {
|
|
|
|
- status.selects = Array.from(filterShapes);
|
|
|
|
|
|
+ const canSelect = (shape: EntityShape) => {
|
|
|
|
+ const id = shape.id();
|
|
|
|
+ return !!(id && store.items.some((item) => item.id === id));
|
|
|
|
+ };
|
|
|
|
+ const listener = (shape: EntityShape) => {
|
|
|
|
+ const bus: SelectionManageBus = mitt();
|
|
|
|
+ const stop = watch(
|
|
|
|
+ () => canSelect(shape),
|
|
|
|
+ (exixts, _, onCleanup) => {
|
|
|
|
+ if (!exixts) {
|
|
|
|
+ bus.emit("del", shape);
|
|
|
|
+ } else {
|
|
|
|
+ onCleanup(on(shape, () => bus.emit("update", shape)));
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- { flush: "post" }
|
|
|
|
|
|
+ { immediate: true }
|
|
);
|
|
);
|
|
|
|
+ return { stop, bus };
|
|
|
|
+ };
|
|
|
|
|
|
- return {
|
|
|
|
- addShapes,
|
|
|
|
- delShapes,
|
|
|
|
- watchSelection,
|
|
|
|
|
|
+ return { canSelect, listener };
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+export const useGetShapeSelectionManage = installGlobalVar(() => {
|
|
|
|
+ const compManages: Partial<Record<ShapeType, SelectionManage>> = {};
|
|
|
|
+ for (const type of shapeTypes) {
|
|
|
|
+ compManages[type] =
|
|
|
|
+ components[type].useGetSelectionManage &&
|
|
|
|
+ components[type].useGetSelectionManage();
|
|
|
|
+ }
|
|
|
|
+ const storeManage = useStoreSelectionManage();
|
|
|
|
+ const getShapeBelong = useGetShapeBelong();
|
|
|
|
+ return (shape: EntityShape) => {
|
|
|
|
+ const bl = getShapeBelong(shape);
|
|
|
|
+ if (!bl) return;
|
|
|
|
+ if (compManages[bl.type]) {
|
|
|
|
+ return compManages[bl.type];
|
|
|
|
+ } else if (bl.isSelf) {
|
|
|
|
+ return storeManage;
|
|
|
|
+ }
|
|
};
|
|
};
|
|
-};
|
|
|
|
|
|
+});
|
|
|
|
|
|
export const useSelectionRevise = () => {
|
|
export const useSelectionRevise = () => {
|
|
|
|
+ const getShapeSelectionManage = useGetShapeSelectionManage();
|
|
const mParts = useMountParts();
|
|
const mParts = useMountParts();
|
|
const status = useMouseShapesStatus();
|
|
const status = useMouseShapesStatus();
|
|
const store = useStore();
|
|
const store = useStore();
|
|
- const eSelection = useExcludeSelection()
|
|
|
|
-
|
|
|
|
- const { addShapes, delShapes, watchSelection } = useWatchSelection();
|
|
|
|
-
|
|
|
|
- useSelectionShowIcons();
|
|
|
|
-
|
|
|
|
- const getFormatChildren = useGetFormalChildren();
|
|
|
|
- const filterSelect = debounce(() => {
|
|
|
|
- const children = getFormatChildren();
|
|
|
|
- const mouseSelects = status.selects.filter((shape) =>
|
|
|
|
- !eSelection.value.includes(shape.id()) && children.includes(shape)
|
|
|
|
- );
|
|
|
|
- status.selects = mouseSelects;
|
|
|
|
- }, 16);
|
|
|
|
- store.bus.on("delItemAfter", filterSelect);
|
|
|
|
- store.bus.on("clearAfter", filterSelect);
|
|
|
|
- store.bus.on("dataChangeAfter", filterSelect);
|
|
|
|
- store.bus.on("setCurrentLayerAfter", filterSelect);
|
|
|
|
-
|
|
|
|
const { selections: rectSelects } = useSelection();
|
|
const { selections: rectSelects } = useSelection();
|
|
|
|
+ let selfSet = false;
|
|
|
|
+ const setSelectShapes = (shapes: EntityShape[]) => {
|
|
|
|
+ selfSet = true;
|
|
|
|
+ status.selects = shapes;
|
|
|
|
+ selfSet = false;
|
|
|
|
+ };
|
|
|
|
+
|
|
let initSelections: EntityShape[] = [];
|
|
let initSelections: EntityShape[] = [];
|
|
- let stopWatchSelection = watchSelection();
|
|
|
|
watch(
|
|
watch(
|
|
() => rectSelects.value && [...rectSelects.value],
|
|
() => rectSelects.value && [...rectSelects.value],
|
|
(rectSelects, oldRectSelects) => {
|
|
(rectSelects, oldRectSelects) => {
|
|
if (!oldRectSelects) {
|
|
if (!oldRectSelects) {
|
|
initSelections = [...status.selects];
|
|
initSelections = [...status.selects];
|
|
- stopWatchSelection();
|
|
|
|
} else if (!rectSelects) {
|
|
} else if (!rectSelects) {
|
|
initSelections = [];
|
|
initSelections = [];
|
|
- stopWatchSelection = watchSelection();
|
|
|
|
} else {
|
|
} else {
|
|
- status.selects = Array.from(
|
|
|
|
- addShapes(new Set(initSelections), rectSelects)
|
|
|
|
- );
|
|
|
|
- // filterSelect()
|
|
|
|
|
|
+ setSelectShapes(initSelections.concat(rectSelects));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
);
|
|
);
|
|
|
|
+ useShapesIcon(computed(() => status.selects.concat(rectSelects.value || [])));
|
|
|
|
|
|
- const ids = computed(() => [...new Set(status.selects.map((item) => item.id()))]);
|
|
|
|
|
|
+ const filterSelect = debounce(() => {
|
|
|
|
+ const selects = new Set<EntityShape>();
|
|
|
|
+ for (const shape of status.selects) {
|
|
|
|
+ const children = getFlatChildren(shape);
|
|
|
|
+ children.forEach((childShape) => {
|
|
|
|
+ const manage = getShapeSelectionManage(childShape);
|
|
|
|
+ if (manage?.canSelect(childShape)) {
|
|
|
|
+ selects.add(childShape);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ setSelectShapes([...selects]);
|
|
|
|
+ }, 16);
|
|
|
|
+ store.bus.on("delItemAfter", filterSelect);
|
|
|
|
+ store.bus.on("clearAfter", filterSelect);
|
|
|
|
+ store.bus.on("dataChangeAfter", filterSelect);
|
|
|
|
+ store.bus.on("setCurrentLayerAfter", filterSelect);
|
|
|
|
+ watch(
|
|
|
|
+ () => status.selects,
|
|
|
|
+ () => selfSet || filterSelect(),
|
|
|
|
+ { flush: "sync" }
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ const ids = computed(() => [
|
|
|
|
+ ...new Set(status.selects.map((item) => item.id())),
|
|
|
|
+ ]);
|
|
const groupConfig = {
|
|
const groupConfig = {
|
|
id: onlyId(),
|
|
id: onlyId(),
|
|
createTime: Date.now(),
|
|
createTime: Date.now(),
|
|
@@ -403,43 +361,29 @@ export const useSelectionRevise = () => {
|
|
data: { ...groupConfig, ids: ids.value },
|
|
data: { ...groupConfig, ids: ids.value },
|
|
key: groupConfig.id,
|
|
key: groupConfig.id,
|
|
onUpdateShape(data: GroupData) {
|
|
onUpdateShape(data: GroupData) {
|
|
- status.selects;
|
|
|
|
- data.ids;
|
|
|
|
|
|
+ // status.selects;
|
|
|
|
+ // data.ids;
|
|
},
|
|
},
|
|
onDelShape() {
|
|
onDelShape() {
|
|
- status.selects = [];
|
|
|
|
|
|
+ setSelectShapes([]);
|
|
},
|
|
},
|
|
onAddShape(data: GroupData) {
|
|
onAddShape(data: GroupData) {
|
|
history.onceTrack(() => {
|
|
history.onceTrack(() => {
|
|
const ids = data.ids;
|
|
const ids = data.ids;
|
|
- const cIds = ids.filter((id) => store.getType(id) !== "group");
|
|
|
|
-
|
|
|
|
const groups = store.typeItems.group;
|
|
const groups = store.typeItems.group;
|
|
const exists = groups?.some((group) => {
|
|
const exists = groups?.some((group) => {
|
|
- if (group.ids.length !== cIds.length) return false;
|
|
|
|
- const diff = diffArrayChange(group.ids, cIds);
|
|
|
|
|
|
+ if (group.ids.length !== ids.length) return false;
|
|
|
|
+ const diff = diffArrayChange(group.ids, ids);
|
|
return diff.added.length === 0 && diff.deleted.length == 0;
|
|
return diff.added.length === 0 && diff.deleted.length == 0;
|
|
});
|
|
});
|
|
if (exists) return;
|
|
if (exists) return;
|
|
|
|
|
|
- let selects = new Set(status.selects);
|
|
|
|
- for (let i = 0; i < ids.length; i++) {
|
|
|
|
- if (store.getType(ids[i]) === "group") {
|
|
|
|
- delShapes(
|
|
|
|
- selects,
|
|
|
|
- status.selects.filter((shape) => shape.id() === ids[i])
|
|
|
|
- );
|
|
|
|
- store.delItem("group", ids[i]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- store.addItem("group", { ...data, ids: cIds });
|
|
|
|
|
|
+ store.addItem("group", { ...data, ids });
|
|
showItemId.cycle(data.id, async () => {
|
|
showItemId.cycle(data.id, async () => {
|
|
await nextTick();
|
|
await nextTick();
|
|
const $stage = stage.value!.getNode();
|
|
const $stage = stage.value!.getNode();
|
|
const addShape = $stage.findOne("#" + data.id) as EntityShape;
|
|
const addShape = $stage.findOne("#" + data.id) as EntityShape;
|
|
- addShapes(selects, [addShape]);
|
|
|
|
- status.selects = Array.from(selects);
|
|
|
|
|
|
+ setSelectShapes([addShape]);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
},
|
|
},
|