From dd791856c274390af9fc4ec2fde5872ff1b06004 Mon Sep 17 00:00:00 2001 From: Youzini-afk <13153778771cx@gmail.com> Date: Sat, 11 Apr 2026 02:04:59 +0800 Subject: [PATCH] Fix mobile graph touch mouse interaction --- ui/graph-renderer.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ui/graph-renderer.js b/ui/graph-renderer.js index a2deddc..08360fb 100644 --- a/ui/graph-renderer.js +++ b/ui/graph-renderer.js @@ -207,6 +207,7 @@ export class GraphRenderer { this.lastMouse = { x: 0, y: 0 }; /** @type {{ startX: number, startY: number, lastX: number, lastY: number, nodeCandidate: object|null, moved: boolean } | null} */ this._touchSession = null; + this._suppressMouseUntil = 0; this.animId = null; @@ -780,6 +781,11 @@ export class GraphRenderer { return; } e.preventDefault(); + this._markTouchInteraction(); + this.dragNode = null; + this.isDragging = false; + this.isPanning = false; + this._dragStartMouse = null; const t = e.touches[0]; const { x, y } = this._canvasToWorld(t.clientX, t.clientY); this._touchSession = { @@ -794,6 +800,7 @@ export class GraphRenderer { c.addEventListener('touchmove', (e) => { if (!this._touchSession || e.touches.length !== 1) return; e.preventDefault(); + this._markTouchInteraction(); const t = e.touches[0]; const dx = t.clientX - this._touchSession.lastX; const dy = t.clientY - this._touchSession.lastY; @@ -810,8 +817,13 @@ export class GraphRenderer { }, { passive: false }); c.addEventListener('touchend', (e) => { if (!this._touchSession) return; + this._markTouchInteraction(); const sess = this._touchSession; this._touchSession = null; + this.dragNode = null; + this.isDragging = false; + this.isPanning = false; + this._dragStartMouse = null; if (!sess.moved && sess.nodeCandidate) { this.selectedNode = sess.nodeCandidate; if (this.onNodeSelect) this.onNodeSelect(sess.nodeCandidate); @@ -820,10 +832,23 @@ export class GraphRenderer { } }); c.addEventListener('touchcancel', () => { + this._markTouchInteraction(); this._touchSession = null; + this.dragNode = null; + this.isDragging = false; + this.isPanning = false; + this._dragStartMouse = null; }); } + _markTouchInteraction() { + this._suppressMouseUntil = Date.now() + 650; + } + + _shouldIgnoreMouseEvent() { + return Date.now() < this._suppressMouseUntil; + } + _canvasToWorld(clientX, clientY) { const rect = this.canvas.getBoundingClientRect(); const x = (clientX - rect.left - this.offsetX) / this.scale; @@ -843,6 +868,7 @@ export class GraphRenderer { } _onMouseDown(e) { + if (this._shouldIgnoreMouseEvent()) return; const { x, y } = this._canvasToWorld(e.clientX, e.clientY); const node = this._findNodeAt(x, y); this.lastMouse = { x: e.clientX, y: e.clientY }; @@ -858,6 +884,7 @@ export class GraphRenderer { } _onMouseMove(e) { + if (this._shouldIgnoreMouseEvent()) return; const { x, y } = this._canvasToWorld(e.clientX, e.clientY); if (this.isDragging && this.dragNode) { @@ -881,6 +908,7 @@ export class GraphRenderer { } _onMouseUp() { + if (this._shouldIgnoreMouseEvent()) return; if (this.dragNode) { this._clampNodeToRegion(this.dragNode); this.dragNode.pinned = false; @@ -919,6 +947,7 @@ export class GraphRenderer { } _onDoubleClick(e) { + if (this._shouldIgnoreMouseEvent()) return; const { x, y } = this._canvasToWorld(e.clientX, e.clientY); const node = this._findNodeAt(x, y); if (node) {