From d425af5d5a10a5ee6383be4fff3154c2ba8ad795 Mon Sep 17 00:00:00 2001 From: zhe-he Date: Fri, 27 Dec 2024 11:59:17 +0800 Subject: [PATCH] fix: When holding Shift to enable multi-selection, mouse:over and mouse:out do not behave as expected --- CHANGELOG.md | 2 ++ src/canvas/SelectableCanvas.spec.ts | 24 ++++++++++++++++++++++++ src/canvas/SelectableCanvas.ts | 11 +++++++++++ 3 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f35b819583e..f05000dbeb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [next] +- fix(): When holding Shift to enable multi-selection, mouse:over and mouse:out do not behave as expected [#10037](https://github.com/fabricjs/fabric.js/issues/10337) + ## [6.5.3] - fix(ColorMatrix): Restore correct alpha for JS colorMatrix filter [#10313](https://github.com/fabricjs/fabric.js/pull/10313) diff --git a/src/canvas/SelectableCanvas.spec.ts b/src/canvas/SelectableCanvas.spec.ts index 8d99bcb1775..5c10bcd36ae 100644 --- a/src/canvas/SelectableCanvas.spec.ts +++ b/src/canvas/SelectableCanvas.spec.ts @@ -499,4 +499,28 @@ describe('Selectable Canvas', () => { expect(canvas._hoveredTarget).toBe(undefined); }); }); + + describe('findTarget', () => { + test('Holding down selection key allows you to select shapes that are covered by the active selection.', () => { + const a = new FabricObject({ width: 100, height: 100 }); + const b = new FabricObject({ width: 100, height: 100 }); + const c = new FabricObject({ width: 100, height: 100 }); + const canvas = new Canvas(); + canvas.add(a, b, c); + const as = new ActiveSelection([a, b]); + canvas.setActiveObject(as); + + const fakeMouse = new MouseEvent('mousemove', { + clientX: 50, + clientY: 50, + }); + const fakeMouseShift = new MouseEvent('mousemove', { + clientX: 50, + clientY: 50, + shiftKey: true, + }); + expect(canvas.findTarget(fakeMouse)).toBe(as); + expect(canvas.findTarget(fakeMouseShift)).toBe(c); + }); + }); }); diff --git a/src/canvas/SelectableCanvas.ts b/src/canvas/SelectableCanvas.ts index 7b1dc3bd6f0..2bb4a65e169 100644 --- a/src/canvas/SelectableCanvas.ts +++ b/src/canvas/SelectableCanvas.ts @@ -51,6 +51,7 @@ import type { CanvasOptions } from './CanvasOptions'; import { canvasDefaults } from './CanvasOptions'; import { Intersection } from '../Intersection'; import { isActiveSelection } from '../util/typeAssertions'; +import type { ActiveSelection } from '../shapes/ActiveSelection'; /** * Canvas class @@ -729,6 +730,16 @@ export class SelectableCanvas // check pointer is over active selection and possibly perform `subTargetCheck` this.searchPossibleTargets([activeObject], pointer) ) { + // If you hold down selection key, you can select elements that are blocked by active selection. + if (this._isSelectionKeyPressed(e)) { + const other = this.searchPossibleTargets(this._objects, pointer); + if ( + other && + !(activeObject as ActiveSelection).contains(other, true) + ) { + return other; + } + } // active selection does not select sub targets like normal groups return activeObject; } else if (