Add 'reverse' option to wheel gesture#660
Conversation
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 7f07adb:
|
|
@dbismut could you please take a look? |
|
Hi @jeroenkroese thanks for the PR. Unfortunately I don't have a lot of time to dedicate to OSS atm. What's the benefit of this vs using the |
|
Hi @dbismut, I'm sorry for the late reply to your swift response. I got distracted. I've created a simple reproduction of what I'm trying to achieve. Unfortunately, I could not get it working using the https://codesandbox.io/p/sandbox/use-gesture-zoom-reverse-23npzv?file=%2Fsrc%2FApp.js |
|
Hi @dbismut, I just noticed that I'd left the codesandbox on private. It should be public now. Do you think this behaviour should be accomplishable by using the https://codesandbox.io/p/sandbox/use-gesture-zoom-reverse-23npzv |
travisbreaks
left a comment
There was a problem hiding this comment.
Implementation is clean — config resolver, docs update, and a live example with a toggle checkbox. The wheel engine change is minimal (sign flip on delta).
Worth noting: PR #171 proposed something similar and was closed with the reasoning that it's achievable in userland by negating the offset. Has the maintainer stance on this changed, or is there a case where userland negation doesn't cover it (e.g., interaction with bounds or rubberband)?
The docs example is a nice touch — interactive demo makes the behavior immediately clear.
travisbreaks
left a comment
There was a problem hiding this comment.
Nice work, @jeroenkroese. Circling back with a deeper look at the implementation.
Prior art acknowledgment: This picks up where #171 left off. The key difference — and what makes this PR more compelling — is the concrete use case around bounds interaction. In #171, @dbismut suggested userland negation (offset * -1), but as both @JJK801 and you've demonstrated, that breaks down when bounds and from are in play because the engine's internal movement tracking and clamping logic operates on the pre-inversion values. Negating after the fact means bounds clip in the wrong direction. That's the real justification for handling this at the engine level.
Implementation review:
The core change in WheelEngine.ts is exactly right — V.subTo vs V.addTo on _movement before bounds clamping runs. This ensures clampStateInternalMovementToBounds operates on the correctly-signed movement, which is the whole point. Clean and minimal.
A few observations:
-
_deltasign: The delta itself isn't negated — only the accumulation direction flips. This meansstate.deltain the handler callback will still report the raw wheel direction whilemovement/offsetare reversed. That's probably the right call (preserves raw event info), but it's worth documenting explicitly since someone debugging might expect delta and movement to agree in sign. -
Dynamic toggling: The docs example shows a checkbox toggling
reverseat runtime. Since the config resolver runs on each gesture start, toggling mid-gesture could produce a discontinuity inoffset(the accumulated movement suddenly flips direction). The test only covers a static config. Might be worth either (a) adding a test for mid-session toggle, or (b) noting in docs thatreverseis best set before gesture begins. -
Changeset missing: The changeset bot flagged this. You'll need one for the version bump — this would be a
patchon@use-gesture/core. -
Scroll engine parity: Any reason this is wheel-only and not also available on
ScrollEngine? The sameboundsinteraction issue could apply there. Not a blocker, just curious about scope.
Overall this is a well-scoped addition. The type updates are thorough (WheelConfig, UserWheelConfig, InternalConfig), docs include an interactive example, and the test validates the sign arithmetic. The +76/-6 ratio is healthy for a feature that touches config resolution, engine logic, types, docs, and tests.
This PR adds a
reverseoption to the wheel gesture, which inverts the direction of wheel scrolling. A few years ago, a similar PR #171 has been closed with the reason that the inversion could easily be done in userland.In my scenario, I'm using multiple gestures (drag, pinch-to-zoom, and wheel) to navigate around a canvas element, and I'm using the
fromandboundsproperties to limit the canvas movement. This led to some complications when I tried to invert the direction of the wheel scroll. Without having thereverseoption, it would require a complex bounds calculation which would be the inverse of the bounds which I'm already calculating for thedraggesture. This was my first approach, however I ran into some weird behaviour which is was not able to easily fix.The
reverseoption that is introduced by this PR allows developers in the invert the wheel gesture, while allowing to use the sameboundscalculation that is used by thedraggesture. This will make it easier for developers that wish to implement drag and wheel gesture behaviour similar to something like excalidraw.com.