From 3dc6b6b3ca8f6ef0c47a2b960a48be6d3da277ef Mon Sep 17 00:00:00 2001 From: llama Date: Mon, 28 Jul 2025 17:01:50 +0800 Subject: [PATCH] Refactor IO fill tool target check logic (#4222) * populate canvas.targets with subtargets during mouse events * use canvas.targets instead of findTargetInGroup * remove unused findTargetInGroup --- ts/routes/image-occlusion/mask-editor.ts | 2 ++ ts/routes/image-occlusion/tools/lib.ts | 15 --------------- ts/routes/image-occlusion/tools/tool-fill.ts | 6 ++---- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/ts/routes/image-occlusion/mask-editor.ts b/ts/routes/image-occlusion/mask-editor.ts index b632abf98..6d4d0d284 100644 --- a/ts/routes/image-occlusion/mask-editor.ts +++ b/ts/routes/image-occlusion/mask-editor.ts @@ -109,6 +109,8 @@ function initCanvas(): fabric.Canvas { // snap rotation around 0 by +-3deg fabric.Object.prototype.snapAngle = 360; fabric.Object.prototype.snapThreshold = 3; + // populate canvas.targets with subtargets during mouse events + fabric.Group.prototype.subTargetCheck = true; // disable rotation when selecting canvas.on("selection:created", () => { const g = canvas.getActiveObject(); diff --git a/ts/routes/image-occlusion/tools/lib.ts b/ts/routes/image-occlusion/tools/lib.ts index ab410cbad..740f135af 100644 --- a/ts/routes/image-occlusion/tools/lib.ts +++ b/ts/routes/image-occlusion/tools/lib.ts @@ -105,21 +105,6 @@ export const unGroupShapes = (canvas: fabric.Canvas): void => { redraw(canvas); }; -/** Check for the target within a (potentially nested) group - * NOTE: assumes that masks do not overlap */ -export const findTargetInGroup = (group: fabric.Group, p: fabric.Point): fabric.Object | undefined => { - if (!group) { return; } - const point = fabric.util.transformPoint(p, fabric.util.invertTransform(group.calcOwnMatrix())); - for (const shape of group.getObjects()) { - if (shape instanceof fabric.Group) { - const ret = findTargetInGroup(shape, point); - if (ret) { return ret; } - } else if (shape.containsPoint(point)) { - return shape; - } - } -}; - const copyItem = (canvas: fabric.Canvas): void => { const activeObject = canvas.getActiveObject(); if (!activeObject) { diff --git a/ts/routes/image-occlusion/tools/tool-fill.ts b/ts/routes/image-occlusion/tools/tool-fill.ts index 97c574313..0f94ec2e7 100644 --- a/ts/routes/image-occlusion/tools/tool-fill.ts +++ b/ts/routes/image-occlusion/tools/tool-fill.ts @@ -4,7 +4,7 @@ import { fabric } from "fabric"; import { get, type Readable } from "svelte/store"; -import { findTargetInGroup, stopDraw } from "./lib"; +import { stopDraw } from "./lib"; import { undoStack } from "./tool-undo-redo"; export const fillMask = (canvas: fabric.Canvas, colourStore: Readable): void => { @@ -17,9 +17,7 @@ export const fillMask = (canvas: fabric.Canvas, colourStore: Readable): stopDraw(canvas); canvas.on("mouse:down", function(o) { - const target = o.target instanceof fabric.Group - ? findTargetInGroup(o.target, canvas.getPointer(o.e) as fabric.Point) - : o.target; + const target = o.target instanceof fabric.Group ? canvas.targets[0] : o.target; const colour = get(colourStore); if (!target || target.fill === colour) { return; } target.fill = colour;