visx
visx copied to clipboard
Zoom: Enable customisation of event handlers
We're using @visx/zoom for a project to zoom/pan a combined visualisation of charts. Basically, it's a list of bar charts which can be scrolled. Additionally, the view can be zoomed/panned.
So, to overcome the shared interaction of the scroll wheel to scroll or zoom the view, we would like to use the control-key as key modifier to enable the zooming/panning. As the control-key is used by @use-gesture to trigger the pinch-event, we need to modify the settings used by @visx/zoom to initialise useGesture:
useGesture(
{
onDragStart: ({ event }) => {
if (!(event instanceof KeyboardEvent)) dragStart(event);
},
onDrag: ({ event, pinching, cancel }) => {
if (pinching) {
cancel();
dragEnd();
} else if (!(event instanceof KeyboardEvent)) {
dragMove(event);
}
},
onDragEnd: dragEnd,
onPinch: handlePinch,
onWheel: ({ event, active, pinching }) => {
if (
// Outside of Safari, the wheel event is fired together with the pinch event
pinching ||
// currently onWheelEnd emits one final wheel event which causes 2x scale
// updates for the last tick. ensuring that the gesture is active avoids this
!active
) {
return;
}
handleWheel(event);
},
},
{ target: containerRef, eventOptions: { passive: false }, drag: { filterTaps: true } },
);
So, I would like to suggest to enable the customisation of the useGesture-options as well as the event handlers (e.g. handleWheel
) through adding additional properties to the Zoom-component, so that we can provide custom handlers/options.
Basically doing something like:
<Zoom<SVGSVGElement>
height={height}
width={width}
onWheel={customHandleWheel}
useGestureConfig={customUseGestureConfig}
>
{(zoom) => {
...
}}
</Zoom>
Hey @jsjohann , this sounds good to me! Would you be up for a PR to add this config hook? I'd be happy to review and release!
@williaster Thanks for the quick answer! Sure, I can try and have a look :)
I'll try solving this as it will also solve #1845. I'll follow the approach above and accept a useGestureConfig
prop
So I ended up accepting a createGestureHandlers
prop because I figured out people using this would most likely need access to the ProvidedZoom<ElementType>
object in order to use some of its properties