|
155 | 155 | // ============================================================ |
156 | 156 | // Pointer state machine |
157 | 157 | // |
158 | | - // - every pointer enters the map; .textBox only suppresses PAN initiation |
159 | | - // - single-finger touch never pans (reserved for Reader's swipe-to-flip) |
| 158 | + // - every pointer enters the map; .textBox suppresses PAN initiation for |
| 159 | + // mouse/pen only (drag selection) — touch pans everywhere, exactly like |
| 160 | + // the old panzoom touch path, which handled single-finger touches |
| 161 | + // unconditionally (its onTouch option only gated preventDefault) |
| 162 | + // - single-finger touch pan COEXISTS with Reader's swipe-to-flip: touch |
| 163 | + // events aren't retargeted by pointer capture, so the window-level swipe |
| 164 | + // handlers still see them and stay edge-gated (#186) |
160 | 165 | // - capture is deferred until DRAG_THRESHOLD so gutter-button clicks and |
161 | 166 | // text-selection drags behave exactly as before |
162 | 167 | // - two pointers always upgrade to pinch; back down to one re-baselines |
163 | | - // as a fresh mouse/pen pan, touch returns to idle |
| 168 | + // as a fresh pan with the remaining pointer |
164 | 169 | // ============================================================ |
165 | 170 |
|
166 | 171 | const DRAG_THRESHOLD = 5; |
|
205 | 210 | return; |
206 | 211 | } |
207 | 212 |
|
208 | | - if (e.pointerType === 'touch') return; // swipe-to-flip's domain |
209 | | - if ((e.target as HTMLElement).closest('.textBox')) return; // selection |
| 213 | + // Mouse/pen on a text box is a selection drag, never a pan; touch has no |
| 214 | + // drag-selection gesture and panned over text in production too. |
| 215 | + if (e.pointerType !== 'touch' && (e.target as HTMLElement).closest('.textBox')) return; |
210 | 216 | if (e.button !== 0) return; |
211 | 217 |
|
212 | 218 | if (controller.isActive) controller.finishNow(); |
|
254 | 260 | controller.pinchStart(points()); // re-baseline on the new pair |
255 | 261 | } else { |
256 | 262 | controller.pinchEnd(); |
| 263 | + // The remaining pointer continues as a pan — for touch too, matching |
| 264 | + // the old panzoom pinch→drag handoff. |
257 | 265 | const rest = points()[0]; |
258 | 266 | const restId = [...activePointers.keys()][0]; |
259 | | - if (rest && rest.type !== 'touch') { |
| 267 | + if (rest) { |
260 | 268 | beginPan({ pointerId: restId, clientX: rest.x, clientY: rest.y }); |
261 | 269 | } |
262 | 270 | } |
|
0 commit comments