visx icon indicating copy to clipboard operation
visx copied to clipboard

Zoom: Enable customisation of event handlers

Open jsjohann opened this issue 1 year ago • 4 comments

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>

jsjohann avatar Feb 12 '24 17:02 jsjohann

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 avatar Feb 18 '24 02:02 williaster

@williaster Thanks for the quick answer! Sure, I can try and have a look :)

jsjohann avatar Feb 19 '24 12:02 jsjohann

I'll try solving this as it will also solve #1845. I'll follow the approach above and accept a useGestureConfig prop

RamonEspinosa avatar Jun 01 '24 00:06 RamonEspinosa

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

RamonEspinosa avatar Jun 01 '24 05:06 RamonEspinosa