feat(core): doubleClickDragZoom gesture#10327
Conversation
Adds the Google Maps-style touch zoom: a quick tap followed by a press-and-drag with the same finger zooms in/out continuously without ever using the second finger. Useful for one-handed touch interaction. - New DOUBLE_TAP_DRAG event channel routed through pointerdown/move/up. - Tap timing constants tuned for snap response without false triggers. - _onPointerDown promotes a stored single tap to a one-finger zoom session when the second tap lands close enough in time and space. - _onPointerMove drives controllerState.zoom relative to vertical drag; _onPointerUp finalizes and suppresses the trailing dblclick. - pan handlers short-circuit while a one-finger zoom is active.
7cea955 to
b1e6a61
Compare
| case 'pointerdown': | ||
| return this._onDoubleClickDragPointerDown(event); | ||
| case 'pointermove': | ||
| return this._onDoubleClickDragPointerMove(event); | ||
| case 'pointerup': | ||
| case 'pointercancel': | ||
| return this._onDoubleClickDragPointerUp(event); |
There was a problem hiding this comment.
For follow up, does mjoinir need a 'dblclickmove'? There isn't a second up pointer event so I'm not sure
| PINCH: ['pinchstart', 'pinchmove', 'pinchend'], | ||
| MULTI_PAN: ['multipanstart', 'multipanmove', 'multipanend'], | ||
| DOUBLE_CLICK: ['dblclick'], | ||
| DOUBLE_CLICK_DRAG: ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'], |
There was a problem hiding this comment.
@Pessimistress suggested a good refactor would be to implement a new recognizer in mjolnir for this. It'd simplify the controller compared to using raw pointer events.
There was a problem hiding this comment.
Id like to gain some perspective on how platforms like OS organize their gesture recognition across mobile, mouse, and Vision Pro, I strongly agree gesture recognition should be managed within mjolnir.
There was a problem hiding this comment.
@Pessimistress @chrisgervang thinking about this a little more.
The current list of mjolnir gestures feel complete. However, I agree this gesture is reusable, a new recognizer would simplify the controller.
I am propsing a new compound gestures section in mjolnir docs where this will be the first addition, and I can use thor.gl as a testing ground for new gestures off the touch surface. The gestures will work the same, just present them in the docs separately?
I can open a heavier RFC consolidating my thor interactivity ideas and start with this doubleTapDrag compound-gesture, but I wanted to use the existing thread here as a starting point of the idea.
Lmk
There was a problem hiding this comment.
This list seems like either incomplete or a different list from what I was expecting to see in the docs (admittedly, this is the first time I've looked at these docs)
The source differentiates between basic and gesture recognizers
I expected to see "double click" and similar in the docs, but they don't seem to be included.
"double click drag" seems like another gesture recognizer to join the ranks of "pan drag" - so in that sense, yeah, I think I'm agreeing with you that there needs to be some new doc pages for all of the gesture recognizers, with "double click drag" among them.
Does that help give some direction?
Re: Thor, I have no strong opinion on where you'd like to test - I'd say for now the best path forward for deck 9.4 would be to refactor mjolnir so that we can simplify deck's controller class. The specific hope I have is that we can remove the short circuits in the pan recognizer callbacks on the deck level
Summary
Adds a Google/Apple Maps-style one-finger double-click/tap-and-drag zoom gesture for touch users, exposed as its own controller option:
The gesture lets users:
This gives mobile users a precise one-handed zoom path without requiring pinch zoom, on-screen controls, or desktop double-click zoom behavior.
Comparison Videos
Apple Maps Reference
trim.DD19513B-5915-4050-8865-99E128A9E9A0.MOV
deck.gl GlobeController Demo
trim.31AA42AB-9ACB-4104-8629-9C7557592B20.MOV
The deck.gl demo uses the same one-finger sequence against a GlobeView controller path, matching the mobile map interaction model users already expect.
Why
One-handed mobile map navigation currently has a gap: users can pan with one finger, but controlled zoom generally requires either a second finger or visible zoom controls. The double-click/tap-and-drag gesture is a standard mobile map pattern and lets users zoom in or out while keeping their thumb on the map.
While validating on iOS Safari, repeated touch gestures could also trigger page-level selection/callout affordances over the canvas. This PR keeps the gesture path inside deck.gl while leaving browser UI guard CSS to app developers, with reusable guidance documented for apps using deck.gl controllers.
What Changed
doubleClickDragZoomcontroller option, defaulting totrue.DOUBLE_CLICK_DRAGpointer-event gesture path through pointer down, move, up, and cancel handling.DOUBLE_CLICK_DRAG_PIXELS_PER_ZOOM = 120.dblclickafter the drag gesture so release does not apply a second zoom.doubleClickDragZoomin the Controller API.developer-guide/tips-and-tricks.md#optimization-for-mobileand links to that guidance fromcontroller.md.Behavior Notes
doubleClickDragZoomcontrols this gesture independently fromdoubleClickZoomandtouchZoom.doubleClickZoom: false, because the gesture is continuous pointer-driven zoom rather than double-click zoom.touchZoomis disabled, because this is a distinct one-finger gesture.Validation
MapController supports double-click drag zoom when double click and touch zoom are disabled, covering the full pointer sequence and release behavior.MapController disables double-click drag zoom, covering the new controller option gate.yarn test -- test/modules/core/controllers/controllers.spec.ts test/modules/core/lib/deck.spec.tsgit diff --checkhttp://127.0.0.1:3000/with placeholder map API env vars; only dependency source-map warnings fromarcwere reported.Merge Notes
This is intentionally scoped to the reusable one-finger double-click/tap-and-drag zoom gesture, the dedicated controller option, and app-owned docs/example interaction hardening discovered during mobile validation. GlobeView pointer anchoring/parity work is handled separately in #10307, and the local comparison demo combined the two branches only for manual mobile validation.