fix(canvas): zoom-stable handles and group-scale multi-selection

- Transform handles counter-scale by 1/zoom so they stay constant screen size
- Selection border stroke also counter-scales
- Multi-select resize scales items as a unit from bounding box anchor
- Redraw transform box on viewport zoom/pan via 'moved' listener
This commit is contained in:
Hiren Kangad
2026-03-11 16:59:10 +05:30
parent 155dc6ac01
commit 4ed475c62e
2 changed files with 34 additions and 25 deletions
+10
View File
@@ -42,6 +42,7 @@ export class SelectionManager {
private _onItemTransform: ((item: SceneItem) => void) | null = null;
private _onItemsTransform: ((items: SceneItem[]) => void) | null = null;
private _onObjectDragEnd: ((ids: string[]) => void) | null = null;
private _onViewportMoved: (() => void) | null = null;
// Pointer state
private _pointerDown = false;
@@ -95,6 +96,14 @@ export class SelectionManager {
viewport.on('globalpointermove', this._onPointerMove, this);
viewport.on('pointerup', this._onPointerUp, this);
viewport.on('pointerupoutside', this._onPointerUp, this);
// Redraw transform box on zoom so handles stay constant screen size
this._onViewportMoved = () => {
if (this.selectedIds.size > 0) {
this.transformBox.update(this.getSelectedItems());
}
};
viewport.on('moved', this._onViewportMoved);
}
/** Enable/disable selection interaction (disable during draw/text/eraser tools). */
@@ -464,6 +473,7 @@ export class SelectionManager {
this._viewport.off('globalpointermove', this._onPointerMove, this);
this._viewport.off('pointerup', this._onPointerUp, this);
this._viewport.off('pointerupoutside', this._onPointerUp, this);
if (this._onViewportMoved) this._viewport.off('moved', this._onViewportMoved);
this._overlay.destroy({ children: true });
}
}