ol-carousel touch gestures and swipe physic refinements - #13101
Conversation
Touch swipes were unreliable: starting a vertical page scroll on the carousel could fire a page navigation (pointercancel was handled as a release), horizontal swipes scrolled the page underneath, and after the first page transition the swipe surface went dead on iOS (the pointerdown listener lived on the translated track). - Resolve gesture ownership with an axis lock (8px dead zone, 2:1 horizontal bias) and preventDefault page scroll once locked - Treat pointercancel as an abort that springs home, never a navigation - Move gesture listeners to the untransformed viewport so the whole surface stays swipeable on every page - Smooth velocity (EMA over >=4ms windows, capped, stale samples discarded) so release momentum is stable - Land long drags on the nearest page; momentum carries at most one page beyond it Adds a jest suite covering the gesture state machine.
ol-carousel refinements: - Deepen the cover lookahead from one page to two on the first hover or keyboard focus, so fast page-flipping stays ahead of the loaded range. Skipped on data-saver / 2g connections; fires at most once. - Add arrow-key / Home / End navigation to the page-indicator tablist with a roving tabindex (APG Tabs pattern), plus tests. - Regenerate custom-elements.json to match.
|
@cdrini take a look when you get the chance. |
Add discrete wheel-based paging: a horizontal trackpad swipe (wheel events with deltaX) flips one page per gesture, reusing the existing spring. Only claims horizontal-dominant intent, so vertical scroll and plain mouse wheels pass through; preventDefault owns the gesture and suppresses macOS history back/forward swipe. Momentum tail is swallowed so one physical swipe pages once. Adds 7 unit tests covering direction, vertical pass-through, threshold, momentum lock, gesture-end re-arm, and line-mode normalization.
cdrini
left a comment
There was a problem hiding this comment.
This is a lot of custom code, which I fear will also create some awkward experiences that differ from OS-native touch/scroll interactions on things like acceleration. Is there a reason we're not using the new browser-native CSS scrolling/snapping features?
This is great feedback. I opted to go the custom route to get absolute control of the UI behavior and enable a high level of polish, but after spending some time right now with the latest browser APIs - I'm finding that I underestimated the quality of the built-in native behaviors and the amount of control they provide for customization. I'll do a deeper dive on this. |
|
Just an FYI... a couple of UI behaviors we will lose by going with the native solution:
|
Follow-up polish to #13077 (no linked issue).
Low risk:
<ol-carousel>is not used on any live page yet — it only appears in the design showcase (/developers/design#carousel). Nothing user-facing changes.This refines how the carousel feels to use — mostly around touch and swiping.
carousel.mp4
Swiping feels right now
Covers are ready before you get there
Keyboard
Testing
/developers/design#carousel(use Chrome device mode for touch).Covered by 18 tests in
tests/unit/js/OlCarousel.test.js.Stakeholders
@RayBB