You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks a lot for this absolutely fantastic package!
After testing multiple non-working pinch-zoom-pan solutions for React, i've decided to build my own and use-gesture came up immediately as the de-facto standard for gesture handling in React.
I've followed the great YT series "Building an Animated Image Cropper" by Sam Selikoff and came up with a pretty flexible viewport system similar to 'react-zoom-pan-pinch', also supporting a minimap, spring motion, origin correction and more.
Question 1:
This viewport system needs to work on basically any system and I think I've finally managed to have all gestures required to work nicely together.
I'm still not 100% sure if I'm detecting different gesture states in the right way ...
In particular the touchpad pinch gesture is a bit confusing because it's fired with a 'wheel' event and looks exactly the same as a mousewheel event except for the ctrlKey set to true (and a different scaling in terms of delta).
The touchpad pinch also could be returning a 'scale', 'x' or 'y' axis value with the 'delta' saved in [0] or [1] and with different scaling.
I couldn't find this in the docs so I wonder if there's a better way to handle this scenario.
The zoom handler (below) is also used for example by some UI buttons with a fake gesture state.
const handleZoom = useCallback((gestureState, viewportOrMinimap, memo) => {
if (!viewerSettings.zoom.enabled) return
if (gestureState.last) return
memo ??= { crop: cropRef.current }
const viewportBounds = viewportRef.current.getBoundingClientRect()
let deltaZoom = 0
let origin = [0, 0]
let gestureSignal = 'IGNORED'
if (gestureState.type === 'click') {
// Button click
deltaZoom = Number(gestureState.currentTarget.dataset.zoom) * viewerSettings.zoom.zoomButtonStep
gestureSignal = 'CLICK'
} else if (gestureState.type === 'pointermove' && gestureState.pinching) {
// Touchscreen (mobile) pinch-zoom
deltaZoom = gestureState.delta[0]
origin[0] = gestureState.origin[0] - viewportBounds.width / 2
origin[1] = gestureState.origin[1] - viewportBounds.height / 2
gestureSignal = 'MOBILE PINCH'
} else if (gestureState.type === 'wheel') {
if (gestureState.ctrlKey && gestureState.pinching === true) {
// Touchpad (laptop) pinch-zoom
switch (gestureState.axis) {
case 'scale':
deltaZoom = gestureState.delta[0]
gestureSignal = 'TOUCHPAD PINCH'
break
case 'x':
// ignore x
break
case 'y':
// ignore y
break
}
origin[0] = gestureState.event.clientX - viewportBounds.width / 2
origin[1] = gestureState.event.clientY - viewportBounds.height / 2
} else if (gestureState.pinching !== true && gestureState.axis === 'y') {
// Mouse wheel
deltaZoom = -gestureState.delta[1] / mouseWheelUnits * viewerSettings.zoom.mouseWheelStep
origin[0] = gestureState.event.clientX - viewportBounds.width / 2
origin[1] = gestureState.event.clientY - viewportBounds.height / 2
gestureSignal = 'WHEEL'
}
}
// REST OF THE CODE HAS BEEN REMOVED FOR SIMPLICITY
}), [viewerSettings, setCrop, enforceCrop]
Question 2:
This is not really a question but something that might help other users trying to build something similar: the 'from' parameter could use a simpler and clear explanation, which is extremely important when implementing a custom zoom pinch gesture that, in most cases, requires clamping the zoom scaling with a min / max range.
This took me ages to fully understand and the solution was actually very simple (passing the custom crop to the 'from' parameter).
Apparently without using 'from' parameter, use-gesture internally 'integrates' / 'accumulates' the intensity of the pinch based on how much the user pinch-zoomed so far (I'm not sure how to better explain this, sorry).
This gets complicated when mixing multiple gestures (wheel, touchpad, touch, etc.) and also button clicks ... a common requirement for viewport-based components that work like, for example, Google Maps.
For example, here's another issue which I suspect ran into the exact same problem: #435
I wonder if, without using 'from' parameter, this behavior should also affect the delta at all ... or perhaps if an additional delta property unaffected by the internal zoom level tracked by use-gesture could or should be provided?
Something like 'rawDelta' ? That would be yet another parameter requiring documentation and I don't know if it would be a good design / solution though.
Thanks a lot for this absolutely fantastic package!
After testing multiple non-working pinch-zoom-pan solutions for React, i've decided to build my own and use-gesture came up immediately as the de-facto standard for gesture handling in React.
I've followed the great YT series "Building an Animated Image Cropper" by Sam Selikoff and came up with a pretty flexible viewport system similar to 'react-zoom-pan-pinch', also supporting a minimap, spring motion, origin correction and more.
Question 1:
This viewport system needs to work on basically any system and I think I've finally managed to have all gestures required to work nicely together.
I'm still not 100% sure if I'm detecting different gesture states in the right way ...
In particular the touchpad pinch gesture is a bit confusing because it's fired with a 'wheel' event and looks exactly the same as a mousewheel event except for the ctrlKey set to true (and a different scaling in terms of delta).
The touchpad pinch also could be returning a 'scale', 'x' or 'y' axis value with the 'delta' saved in [0] or [1] and with different scaling.
I couldn't find this in the docs so I wonder if there's a better way to handle this scenario.
The zoom handler (below) is also used for example by some UI buttons with a fake gesture state.
Question 2:
This is not really a question but something that might help other users trying to build something similar: the 'from' parameter could use a simpler and clear explanation, which is extremely important when implementing a custom zoom pinch gesture that, in most cases, requires clamping the zoom scaling with a min / max range.
This took me ages to fully understand and the solution was actually very simple (passing the custom crop to the 'from' parameter).
Apparently without using 'from' parameter, use-gesture internally 'integrates' / 'accumulates' the intensity of the pinch based on how much the user pinch-zoomed so far (I'm not sure how to better explain this, sorry).
This gets complicated when mixing multiple gestures (wheel, touchpad, touch, etc.) and also button clicks ... a common requirement for viewport-based components that work like, for example, Google Maps.
For example, here's another issue which I suspect ran into the exact same problem: #435
I wonder if, without using 'from' parameter, this behavior should also affect the delta at all ... or perhaps if an additional delta property unaffected by the internal zoom level tracked by use-gesture could or should be provided?
Something like 'rawDelta' ? That would be yet another parameter requiring documentation and I don't know if it would be a good design / solution though.
Information:
Checklist:
touch-action: none
to the draggable element.The text was updated successfully, but these errors were encountered: