A kiosk pan stays a pan all the way to the release

The gesture is classified once, on the first movement past 8 px
(`_panLock`), but `_stagePointerUp` ignored that decision and asked
`swipeTarget()` again from the raw start→end vector — audit DEV-1DA1-02.

So a CURVED gesture could be both: a small vertical lead-in locked
`pan`, the plan started following the finger, the trajectory then swept
far sideways, and lifting the finger landed the user on another storey.
On a wall tablet that is the worst kind of surprise — you watch the plan
drag along and end up on a different floor.

The lock is now final: with `_panLock === 'pan'` the floor never
changes, whatever the overall vector looks like, and only a gesture
locked as `swipe` may reach `swipeTarget()`. A motionless tap locks
nothing, so the double-tap zoom reset is untouched.

Regression: demo/smoke_kiosk_pan_lock.mjs — the auditor's curved pan
(both directions and a long diagonal), the mirror case of a swipe that
bends vertically (it never pans, and if it stops qualifying it simply
does nothing), plus the straight swipe / straight pan / double tap /
zoomed-in cases. docs/CANVAS.md §5 and docs/TESTING.md updated.
This commit is contained in:
Sergey
2026-08-04 10:11:57 +03:00
parent 232c4807fd
commit 0af50a74ae
7 changed files with 175 additions and 4 deletions
+10
View File
@@ -197,6 +197,16 @@ was silently excluded from the frame).
the gesture is classified once, on the first movement past 8 px, and
keeps that role until the finger lifts (`_panLock`), so the plan
never slides under a swipe and a vertical drag still pans.
* **The lock is final, at the release too** (audit DEV-1DA1-02). The
release used to ask `swipeTarget()` again from the raw start→end
vector, ignoring the lock — so a *curved* gesture (a short vertical
lead-in that locks `pan`, then a long horizontal sweep) dragged the
plan under the finger and still landed on another storey when it
lifted: the worst kind of surprise on a wall tablet. `_panLock ===
'pan'` now means no floor change, whatever the overall vector ends up
looking like; only a gesture locked as `swipe` may reach
`swipeTarget()`, and it never pans on the way. A motionless tap locks
nothing, so the double-tap zoom reset is untouched.
* **"Home is that way" arrow** — when the content frame is entirely
outside the current view, a small pointer appears at the view edge
in the frame's direction. Clicking it fits the content. Cheap