try to fix box select

This commit is contained in:
SikongJueluo 2025-06-13 22:05:09 +08:00
parent 2270022bbe
commit db71681bdf
1 changed files with 61 additions and 22 deletions

View File

@ -3,7 +3,7 @@
<v-stage class="h-full w-full" ref="stage" :config="stageSize" @mousedown="handleMouseDown" <v-stage class="h-full w-full" ref="stage" :config="stageSize" @mousedown="handleMouseDown"
@mousemove="handleMouseMove" @mouseup="handleMouseUp" @click="handleStageClick"> @mousemove="handleMouseMove" @mouseup="handleMouseUp" @click="handleStageClick">
<v-layer ref="layer"> <v-layer ref="layer">
<template v-for="item in objMap.values()" :key="item.id"> <template ref="canvasObjects" v-for="item in objMap.values()" :key="item.id">
<v-group :config="{ <v-group :config="{
x: item.x, x: item.x,
y: item.y, y: item.y,
@ -13,7 +13,7 @@
@mouseout="handleCanvasObjectMouseOut"> @mouseout="handleCanvasObjectMouseOut">
<v-rect v-show="!isUndefined(item.box)" :config="{ <v-rect v-show="!isUndefined(item.box)" :config="{
...item.box, ...item.box,
visible: !isUndefined(item.box) && item.isHoverring, visible: !isUndefined(item.box) && item.isHoverring && !isDragging,
stroke: 'rgb(125,193,239)', stroke: 'rgb(125,193,239)',
strokeWidth: 2.5, strokeWidth: 2.5,
dash: [10, 5], dash: [10, 5],
@ -42,7 +42,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { isNull, isUndefined, ObjectNode } from "mathjs"; import { isNull, isUndefined } from "mathjs";
import Konva from "konva"; import Konva from "konva";
import type { import type {
VGroup, VGroup,
@ -52,6 +52,8 @@ import type {
VTransformer, VTransformer,
} from "@/utils/VueKonvaType"; } from "@/utils/VueKonvaType";
import { ref, reactive, watch, onMounted, useTemplateRef } from "vue"; import { ref, reactive, watch, onMounted, useTemplateRef } from "vue";
import { list } from "postcss";
import type { IRect } from "konva/lib/types";
const stageSize = { const stageSize = {
width: window.innerWidth, width: window.innerWidth,
@ -147,6 +149,7 @@ onMounted(() => {
}); });
const layer = useTemplateRef<VLayer>("layer"); const layer = useTemplateRef<VLayer>("layer");
const canvasObjects = useTemplateRef<HTMLTemplateElement[]>("canvasObjects")
const transformer = useTemplateRef<VTransformer>("transformer"); const transformer = useTemplateRef<VTransformer>("transformer");
const selectRect = useTemplateRef<VNode>("selectRect"); const selectRect = useTemplateRef<VNode>("selectRect");
const stage = useTemplateRef<VStage>("stage"); const stage = useTemplateRef<VStage>("stage");
@ -209,16 +212,17 @@ function handleDragEnd() {
// Update transformer nodes when selection changes // Update transformer nodes when selection changes
watch(selectedIds, () => { watch(selectedIds, () => {
if (!transformer.value) return; if (isNull(transformer.value)) return;
const nodes = selectedIds.value const nodes = selectedIds.value
.map((id) => { .map((id) => {
return layer.value if (isNull(canvasObjects.value)) return;
?.getNode()
.find((ref: Konva.Node) => ref.attrs.id === id); return canvasObjects.value
.find((ref) => ref.firstChild?.id === id);
}) })
.flat() .flat()
.filter(Boolean) as Konva.Node[]; .filter(Boolean) as unknown as Konva.Node[];
if (!isUndefined(nodes)) transformer.value.getNode().nodes(nodes); if (!isUndefined(nodes)) transformer.value.getNode().nodes(nodes);
}); });
@ -324,24 +328,59 @@ function handleMouseUp() {
height: Math.abs(selectionRectangle.y2 - selectionRectangle.y1), height: Math.abs(selectionRectangle.y2 - selectionRectangle.y1),
}; };
if (isNull(layer.value)) return; for (let [key, shape] of objMap) {
const selected = layer.value.getNode().children.filter((node: Konva.Node) => { const shapeConfig = objMap.get(shape.id);
// Check if rectangle intersects with selection box if (isUndefined(shapeConfig)) {
if (
node === transformer.value?.getNode() ||
node === selectRect.value?.getNode()
)
return false;
const nodeConfig = objMap.get(node.id());
if (isUndefined(nodeConfig) || isUndefined(nodeConfig.box)) {
return; return;
} else if (isUndefined(shapeConfig.box)) {
if (isUndefined(shapeConfig.box)) {
if (
shapeConfig.config.width &&
shapeConfig.config.height &&
shapeConfig.config.rotation
) {
shapeConfig.box = calculateRectBounding(
shapeConfig.config.width,
shapeConfig.config.height,
shapeConfig.config.rotation,
5,
);
} else {
console.error("Could not calculate rect bounding");
return;
}
}
} }
return Konva.Util.haveIntersection(selBox, nodeConfig.box); if (Konva.Util.haveIntersection(selBox, shapeConfig.box as IRect))
}); selectedIds.value.push(shapeConfig.id)
}
selectedIds.value = selected.map((node: Konva.Node) => node.id()); /* const selected = [...objMap.values()].filter((shape) => {
// Check if rectangle intersects with selection box
const shapeConfig = objMap.get(shape.id);
if (isUndefined(shapeConfig)) {
return;
} else if (isUndefined(shapeConfig.box)) {
if (isUndefined(shapeConfig.box)) {
if (
shapeConfig.config.width &&
shapeConfig.config.height &&
shapeConfig.config.rotation
) {
shapeConfig.box = calculateRectBounding(
shapeConfig.config.width,
shapeConfig.config.height,
shapeConfig.config.rotation,
5,
);
} else console.error("Could not calculate rect bounding");
}
return Konva.Util.haveIntersection(selBox, shapeConfig.box as IRect);
});
selectedIds.value = selected.map((shapeConfig) => shapeConfig.id); */
} }
function handleCanvasObjectMouseOver(evt: Event) { function handleCanvasObjectMouseOver(evt: Event) {