fix(label): selected path add point

This commit is contained in:
2026-04-18 21:13:17 +08:00
parent a3748a8539
commit b050af0267
3 changed files with 162 additions and 21 deletions

View File

@@ -899,6 +899,28 @@ const isPaperObjectType = (type: unknown) =>
typeof type === "string" &&
PAPER_OBJECT_TYPES.includes(type as (typeof PAPER_OBJECT_TYPES)[number])
export const ensureEditablePaperPathSelected = (objectId: number) => {
const objectPaths = usePaperStore
.getState()
.getItemsById(objectId)
.filter(
(item): item is paper.Path =>
item instanceof paper.Path && isPaperObjectType(item.data?.type)
)
if (!objectPaths.length) return null
const editablePaths = objectPaths.filter((item) => !item.data?.isHollowPolygon)
const activePath =
editablePaths.find((item) => item.data?.selected) || editablePaths[0] || null
objectPaths.forEach((item) => {
item.data.selected = item === activePath
})
return activePath
}
const isPaperContextHitType = (type: unknown) =>
typeof type === "string" &&
PAPER_CONTEXT_HIT_TYPES.includes(
@@ -1001,6 +1023,13 @@ const resetPaperShapeFillColor = (item: paper.Item) => {
}
const applyPaperSelectedPath = (item: paper.Path | paper.CompoundPath) => {
const objectId = Number(item.data?.id)
const editablePath = Number.isFinite(objectId)
? ensureEditablePaperPathSelected(objectId)
: item instanceof paper.Path && !item.data?.isHollowPolygon
? item
: null
if (item.data.type === "rectangle" && item instanceof paper.Path) {
item.data.selected = true
usePaperSupportStore.getState().handleBufferPaths(item)
@@ -1008,19 +1037,25 @@ const applyPaperSelectedPath = (item: paper.Path | paper.CompoundPath) => {
item.fillColor = item.data.fillColor || item.fillColor || null
} else if (item.data.type === "brush") {
item.data.selected = true
if (item instanceof paper.Path) {
usePaperSupportStore.getState().handleMask(item)
usePaperSupportStore.getState().handleBufferPaths(item)
usePaperSupportStore.getState().handleCircles(item)
if (editablePath) {
usePaperSupportStore.getState().handleMask(editablePath)
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
} else if (item.data.type === "point" && item instanceof paper.Path) {
} else if (item.data.type === "point") {
item.data.selected = true
usePaperSupportStore.getState().handleMask(item)
usePaperSupportStore.getState().handleText(item)
usePaperSupportStore.getState().handleBufferPaths(item)
usePaperSupportStore.getState().handleCircles(item)
if (editablePath) {
usePaperSupportStore.getState().handleMask(editablePath)
usePaperSupportStore.getState().handleText(editablePath)
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
} else if (item.data.type === "polygon") {
item.data.selected = true
if (editablePath) {
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
if (!(item instanceof paper.Path) || !item.data?.isHollowPolygon) {
item.fillColor = item.data.fillColor || item.fillColor || null
}
@@ -6653,15 +6688,17 @@ export const usePaperStore = create<PaperState>((set) => ({
item: paper.Segment,
index: number,
id: number,
_color: any
color: any
) => {
if (!item.next) return null
const hitStrokeColor = clonePaperColor(color) || new paper.Color("#fff")
hitStrokeColor.alpha = 0.001
let bufferPath: paper.Path = new paper.Path(
Object.assign(
{
parent: usePaperStore.getState().group!,
segments: [item.point, item.next],
strokeColor: new paper.Color(0, 0, 0, 0), // 保留 hit 区域,但本体不可见
strokeColor: hitStrokeColor, // 透明度不能为 0否则部分命中/hover 事件会失效
strokeScaling: false,
strokeWidth: 6, // 适度放宽 hover 区域,但避免干扰对象外默认点击
strokeCap: "round",

View File

@@ -1,7 +1,7 @@
import paper from "paper"
import { useLabelStore, useObjectStore } from "../store"
import { useOtherToolsStore } from "../useOtherToolsStore"
import { usePaperStore } from "../usePaperStore"
import { ensureEditablePaperPathSelected, usePaperStore } from "../usePaperStore"
import { usePaperSupportStore } from "../usePaperSupportStore"
import { useTopToolsStore } from "../useTopToolsStore"
@@ -93,6 +93,13 @@ const applySelectedItemVisual = (item: paper.Item) => {
if (!["rectangle", "polygon", "brush", "point"].includes(itemType || ""))
return
const objectId = Number(item.data?.id)
const editablePath = Number.isFinite(objectId)
? ensureEditablePaperPathSelected(objectId)
: item instanceof paper.Path && !item.data?.isHollowPolygon
? item
: null
if (itemType === "rectangle" && item instanceof paper.Path) {
item.data.selected = true
usePaperSupportStore.getState().handleBufferPaths(item)
@@ -100,19 +107,25 @@ const applySelectedItemVisual = (item: paper.Item) => {
item.fillColor = item.data.fillColor || item.fillColor || null
} else if (itemType === "brush") {
item.data.selected = true
if (item instanceof paper.Path) {
usePaperSupportStore.getState().handleMask(item)
usePaperSupportStore.getState().handleBufferPaths(item)
usePaperSupportStore.getState().handleCircles(item)
if (editablePath) {
usePaperSupportStore.getState().handleMask(editablePath)
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
} else if (itemType === "point" && item instanceof paper.Path) {
} else if (itemType === "point") {
item.data.selected = true
usePaperSupportStore.getState().handleMask(item)
usePaperSupportStore.getState().handleText(item)
usePaperSupportStore.getState().handleBufferPaths(item)
usePaperSupportStore.getState().handleCircles(item)
if (editablePath) {
usePaperSupportStore.getState().handleMask(editablePath)
usePaperSupportStore.getState().handleText(editablePath)
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
} else if (itemType === "polygon") {
item.data.selected = true
if (editablePath) {
usePaperSupportStore.getState().handleBufferPaths(editablePath)
usePaperSupportStore.getState().handleCircles(editablePath)
}
if (!(item instanceof paper.Path) || !item.data?.isHollowPolygon) {
item.fillColor = item.data.fillColor || item.fillColor || null
}