From db2b70f15b3ea92441703565d3f0a77df5d67744 Mon Sep 17 00:00:00 2001 From: Leopoldadmin Date: Sun, 28 Jun 2026 23:54:07 +0200 Subject: [PATCH] fix: touch release confirms drawing tool - Add pointercancel listener (treated same as pointerup) - Remove e.preventDefault() from pointerdown/pointerup (was suppressing touch events) - Expand onMouseUp tool list: arc, polygon, revcloud now confirm on release Fixes: object disappears on touch release, tools work same on mobile as desktop --- frontend/src/interaction/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/interaction/index.ts b/frontend/src/interaction/index.ts index 138b666..1fc8ed8 100644 --- a/frontend/src/interaction/index.ts +++ b/frontend/src/interaction/index.ts @@ -58,6 +58,7 @@ export class InteractionEngine { private boundKeyDown: EventListener; private boundMouseMove: EventListener; private boundMouseUp: EventListener; + private boundPointerCancel: EventListener; constructor( canvas: HTMLCanvasElement, @@ -95,6 +96,7 @@ export class InteractionEngine { this.boundKeyDown = this.onKeyDown.bind(this) as EventListener; this.boundMouseMove = this.onMouseMove.bind(this) as EventListener; this.boundMouseUp = this.onMouseUp.bind(this) as EventListener; + this.boundPointerCancel = this.onMouseUp.bind(this) as EventListener; } setElements(elements: CADElement[]): void { @@ -165,6 +167,7 @@ export class InteractionEngine { this.addListener('pointerdown', this.onMouseDown.bind(this) as EventListener); document.addEventListener('pointermove', this.boundMouseMove); document.addEventListener('pointerup', this.boundMouseUp); + document.addEventListener('pointercancel', this.boundPointerCancel); this.addListener('dblclick', this.onDoubleClick.bind(this) as EventListener); this.addListener('wheel', this.onWheel.bind(this) as EventListener, { passive: false } as AddEventListenerOptions); this.addListener('contextmenu', this.onContextMenu.bind(this) as EventListener); @@ -178,6 +181,7 @@ export class InteractionEngine { this.eventListeners = []; document.removeEventListener('pointermove', this.boundMouseMove); document.removeEventListener('pointerup', this.boundMouseUp); + document.removeEventListener('pointercancel', this.boundPointerCancel); document.removeEventListener('keydown', this.boundKeyDown); if (this.animationFrame !== null) { cancelAnimationFrame(this.animationFrame); @@ -222,7 +226,6 @@ export class InteractionEngine { } private onMouseDown(e: MouseEvent): void { - e.preventDefault(); try { this.canvas.setPointerCapture((e as any).pointerId); } catch {} this.isMouseDown = true; this.lastMouseScreen = { x: e.clientX, y: e.clientY }; @@ -342,7 +345,6 @@ export class InteractionEngine { } private onMouseUp(e: MouseEvent): void { - e.preventDefault(); try { this.canvas.releasePointerCapture((e as any).pointerId); } catch {} this.isMouseDown = false; @@ -373,7 +375,7 @@ export class InteractionEngine { const final = this.applyOrtho(snapped.x, snapped.y); const tool = this.state.activeTool; // For 2-point tools: use mouseup position as second point - if (tool === 'line' || tool === 'rect' || tool === 'circle' || tool === 'dimension' || tool === 'leader') { + if (tool === 'line' || tool === 'rect' || tool === 'circle' || tool === 'dimension' || tool === 'leader' || tool === 'arc' || tool === 'polygon' || tool === 'revcloud') { this.state.points.push(final); this.confirmDraw(); return;