Skip to content

Commit 85b7312

Browse files
committed
Mobile fix for touch drag and select
1 parent 81741a1 commit 85b7312

2 files changed

Lines changed: 23 additions & 13 deletions

File tree

‎src/components/organisms/project-canvas/project-canvas.js‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,13 @@ export default define({
106106
});
107107
svg.addEventListener('mousemove', (e) => onMove(host, e, svg));
108108
svg.addEventListener('mouseup', (e) => onUp(host, e, svg));
109-
setupTouch(svg, (o) => {
110-
host.panTransform = `translate(${o.x},${o.y})`;
111-
});
109+
setupTouch(
110+
svg,
111+
(o) => {
112+
host.panTransform = `translate(${o.x},${o.y})`;
113+
},
114+
() => host.tool !== 'select' || host.selectedId !== '',
115+
);
112116
},
113117
shadow: false,
114118
},

‎src/utils/canvasViewport.js‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
/**
22
* Canvas viewport — pan offset and touch event translation.
3-
* Two-finger drag pans the canvas. Single touch draws/selects.
3+
* Two-finger drag pans the canvas.
4+
* Single touch only interacts when a tool is active or object is selected.
45
* @module utils/canvasViewport
56
*/
67

78
/** @type {{ x: number, y: number }} */
89
const offset = { x: 0, y: 0 };
910

10-
/** @type {{ x: number, y: number, dist: number }|null} */
11+
/** @type {{ x: number, y: number }|null} */
1112
let pinch = null;
1213

14+
/** @type {boolean} */
15+
let singleActive = false;
16+
1317
/**
1418
* Get the current pan offset.
1519
* @returns {{ x: number, y: number }}
@@ -20,23 +24,25 @@ export function getOffset() {
2024

2125
/**
2226
* Set up touch handlers on an SVG element.
23-
* Single touch → dispatches equivalent mouse events.
24-
* Two-finger touch → pans the viewport.
2527
* @param {SVGSVGElement} svg
2628
* @param {(offset: { x: number, y: number }) => void} onPan
29+
* @param {() => boolean} shouldInteract - Returns true if single touch should draw/select
2730
*/
28-
export function setupTouch(svg, onPan) {
31+
export function setupTouch(svg, onPan, shouldInteract) {
2932
svg.addEventListener(
3033
'touchstart',
3134
(e) => {
3235
if (e.touches.length === 2) {
3336
e.preventDefault();
37+
singleActive = false;
3438
const mx = (e.touches[0].clientX + e.touches[1].clientX) / 2;
3539
const my = (e.touches[0].clientY + e.touches[1].clientY) / 2;
36-
pinch = { x: mx, y: my, dist: 0 };
40+
pinch = { x: mx, y: my };
3741
return;
3842
}
39-
if (e.touches.length === 1) {
43+
if (e.touches.length === 1 && shouldInteract()) {
44+
e.preventDefault();
45+
singleActive = true;
4046
dispatchMouse(svg, 'mousedown', e.touches[0]);
4147
}
4248
},
@@ -57,7 +63,7 @@ export function setupTouch(svg, onPan) {
5763
onPan(offset);
5864
return;
5965
}
60-
if (e.touches.length === 1) {
66+
if (e.touches.length === 1 && singleActive) {
6167
e.preventDefault();
6268
dispatchMouse(svg, 'mousemove', e.touches[0]);
6369
}
@@ -70,14 +76,14 @@ export function setupTouch(svg, onPan) {
7076
pinch = null;
7177
return;
7278
}
73-
if (e.changedTouches.length === 1) {
79+
if (singleActive && e.changedTouches.length === 1) {
7480
dispatchMouse(svg, 'mouseup', e.changedTouches[0]);
81+
singleActive = false;
7582
}
7683
});
7784
}
7885

7986
/**
80-
* Dispatch a synthetic mouse event from a touch point.
8187
* @param {SVGSVGElement} svg
8288
* @param {string} type
8389
* @param {Touch} touch

0 commit comments

Comments
 (0)