slides: pinch to zoom the canvas, and move it with two fingers - #278
slides: pinch to zoom the canvas, and move it with two fingers#278iamgeo92 wants to merge 1 commit into
Conversation
e716a37 to
d7ef660
Compare
A deck opens at 19-27% on a handset — always needing zoom — and the only way to reach the zoom was the two small buttons in the bottom corner, because multi-touch over the canvas was swallowed outright. Swallowing it was right: a page-level pinch throws Selecto's coordinates off mid-marquee and has crashed the tab. But it left the gesture meaning nothing, on the one device where it is the gesture everybody reaches for first. The pinch now drives the editor's own zoom, anchored on the point between the fingers. setZoom re-centres on the slide, which is right for a button and wrong for a gesture — the thing being pinched would slide out from under the fingers doing the pinching — so zoomAround() compensates the scroll instead. The midpoint's own travel pans at the same time, which is the other half of the same gesture on every canvas tool. The Moveable gesture lock has to stand down for the duration. The first finger has already told Moveable a drag is beginning, which pins the scroller to where that finger landed, so every scroll the zoom performed was snapped straight back and the slide zoomed about the wrong point. The pinch claims the scroller and stops that drag. The page itself still never zooms; one-finger selection, dragging and the marquee are untouched; and the result stays inside the same 0.5x-8x bounds as the buttons.
|
@nyblnet — one for the queue when you have time. A deck opens at 19–27% on a handset, so a phone always needs to zoom, and the only way there was the two small corner buttons — multi-touch over the canvas was swallowed outright. Swallowing it is right (your comment explains the Selecto/marquee crash), but it left the gesture meaning nothing on the one device where everybody reaches for it first. The bit that took longest to find, and the bit I'd most like you to sanity-check: the Moveable gesture lock has to stand down for the duration. The first finger has already told Moveable a drag is starting, which pins the scroller to where that finger landed — so every scroll the zoom performed was snapped straight back and the slide zoomed about the wrong point. Anchor drift went from 640 slide px to 1.6. One file, +81/−7. One-finger selection, dragging and the marquee are untouched, and the page itself still never zooms. |
The problem
A deck opens at 19–27% on a handset — measured on the starter deck:
So a phone always needs to zoom. And the only way to reach the zoom was the
two small buttons in the bottom corner, because multi-touch over the canvas was
swallowed outright:
Swallowing it is right — the comment above it explains why, and it should
stay: a page-level pinch throws Selecto's coordinates off mid-marquee and has
crashed the tab. But it left the gesture meaning nothing at all, on the one
device where it is the first thing everybody reaches for.
The fix
The pinch drives the editor's own zoom. The page still never zooms.
Anchored, not re-centred.
setZoomre-centres the view on the slide, whichis right for a button and wrong for a gesture — the thing being pinched would
slide out from under the fingers doing the pinching.
zoomAround()compensatesthe scroll so the slide point between your fingers stays put. Measured drift
across a full pinch: 1.6 slide px (it was 640 — a whole half-slide — before
the scroll compensation actually landed).
The midpoint pans, so one gesture both scales and moves, as on every map and
canvas tool.
The part that took the longest to find
The Moveable gesture lock has to stand down for the duration. The first
finger has already told Moveable a drag is beginning, and the lock pins the
scroller to wherever that finger landed:
So every scroll the zoom performed was snapped straight back, and the slide
zoomed about the wrong point — the first pinch step anchored correctly and every
step after it collapsed to
scrollLeft = 0. The pinch now claims the scrollerand stops that drag. The lock still does its real job for one-finger drags.
Before / after
Identical gestures both sides: pinch out, pinch again off-centre, pinch back in.
How this was verified
iPhone emulation (390×664, DPR 3,
hasTouch) with real two-point CDP touchsequences:
visualViewport.scale === 1)Gates:
No new user-facing strings, so no i18n catalog changes. No format or kernel
change; nothing under
sync/.Two honest notes
Safari also has non-standard
gesturestart/gesturechangeevents; thisimplementation deliberately uses plain
touchstart/touchmove, which work onboth, but momentum and rubber-banding on real glass deserve a device check.
scripted one-finger drag moves an element much further than the finger
travels. I checked that against
mainwith the same script: the numbers areidentical with and without this change, so it is the known
synthetic-events artifact and not a regression here. Real-mouse/real-finger QA
is still the right bar for the drag path.
Changelog entry — not in the diff, on purpose
CHANGELOG.mdis this repo's named conflict magnet (docs/PARALLEL-WORK.md§3). With several of these open at once, and[Unreleased]being emptied every time a release is cut, a changelog hunk made every one of them conflict on that file and nothing else — twice over. They carry noCHANGELOG.mdchange so they stay mergeable; here is the entry to drop in at release time, or I'll add it back in whatever form you prefer.