d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
501 stars 144 forks source link

How to pan by dragging the trackpad with two fingers? #255

Open Jannchie opened 1 year ago

Jannchie commented 1 year ago

I want to pan by dragging the trackpad with two fingers, not zoom, and I'm not sure how to do that.

247 This issue was raised, but it was closed by himself.

govizlora commented 1 year ago

Dragging the trackpad with two fingers will emit a wheel event, which is equivalent to scrolling the mouse wheel. There is no perfect way to distinguish trackpad dragging from mouse wheel scrolling.

So, supporting panning with two fingers will also make mouse wheel scrolling to pan instead of zoom, which can be unexpected.

But if this is what you want, you could refer to the panOnScroll mode in https://github.com/wbkd/react-flow/blob/main/packages/core/src/container/ZoomPane/index.tsx, which achieves the behavior by replacing the wheel.zoom handler.

I've made a simpler code snippet based on the link above, by removing some sanity checks:

selection
  .call(zoom)
  // Override the default wheel event listener
  .on("wheel.zoom", (event: WheelEvent) => {
    event.preventDefault();

    const currentZoom = selection.property("__zoom").k || 1;

    if (event.ctrlKey) {
      // Use mouse wheel + ctrl key, or trackpad pinch to zoom.
      const nextZoom = currentZoom * Math.pow(2, -event.deltaY * 0.01);
      zoom.scaleTo(selection, nextZoom, pointer(event));
    } else {
      // Use mouse wheel or trackpad with 2 fingers to pan.
      zoom.translateBy(
        selection,
        -(event.deltaX / currentZoom),
        -(event.deltaY / currentZoom)
      );
    }
  });