From 31ea4c0908b0ec61e373ba6c0c1c3c085d624196 Mon Sep 17 00:00:00 2001 From: igurielidze Date: Sat, 21 Mar 2026 18:59:51 +0400 Subject: [PATCH] Add shift+drag to constrain movement to horizontal or vertical axis Holding Shift while dragging locks movement to the dominant axis (whichever has the larger delta from drag start). Works for both single and multi-selection moves. Co-Authored-By: Claude Opus 4.6 (1M context) --- svelte-app/src/lib/canvas/interactions.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/svelte-app/src/lib/canvas/interactions.ts b/svelte-app/src/lib/canvas/interactions.ts index b0ba753..3264abb 100644 --- a/svelte-app/src/lib/canvas/interactions.ts +++ b/svelte-app/src/lib/canvas/interactions.ts @@ -490,6 +490,14 @@ function onMousemove(e: MouseEvent) { if (!pastDragThreshold(pos.x, pos.y, dragState.startX!, dragState.startY!, DRAG_THRESHOLD)) return; dragState.dragActivated = true; } + // Shift: constrain to orthogonal axis (horizontal or vertical) + if (e.shiftKey) { + if (Math.abs(pos.x - dragState.startX!) >= Math.abs(pos.y - dragState.startY!)) { + pos.y = dragState.startY!; + } else { + pos.x = dragState.startX!; + } + } const sym = layout.symbols.find(s => s.id === dragState!.placedId); if (!sym) return; const bb = getAABB(0, 0, sym.w, sym.h, sym.rotation); @@ -508,6 +516,14 @@ function onMousemove(e: MouseEvent) { if (!pastDragThreshold(pos.x, pos.y, dragState.startX!, dragState.startY!, DRAG_THRESHOLD)) return; dragState.dragActivated = true; } + // Shift: constrain to orthogonal axis + if (e.shiftKey) { + if (Math.abs(pos.x - dragState.startX!) >= Math.abs(pos.y - dragState.startY!)) { + pos.y = dragState.startY!; + } else { + pos.x = dragState.startX!; + } + } for (const { id, offsetX, offsetY } of dragState.multiOffsets) { const sym = layout.symbols.find(s => s.id === id); if (!sym) continue;