d3 / d3-zoom

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

Touchmove should trigger filter method #125

Closed ChrisGatzo closed 5 years ago

ChrisGatzo commented 6 years ago

Similarly to touchstarted we want to have the ability to apply a filter to touchmove events. This way we can programmatically allow developers to filter touchmove events instead of allowing all. This implementation is similar to touchstarted. This resolves #124.

magicsunday commented 6 years ago

@mbostock Could you please take a look at this? Its works for me too.

valgussev commented 6 years ago

PR looks great and fixes the issue. Are there any known downsides?

jasonleibowitz commented 6 years ago

I've been waiting on this. Let's get it merged in 🔥

whoisjordangarcia commented 6 years ago

amazing!

jurecka commented 6 years ago

Any plan to merging this fix to master? It would be better to fix touchended function too. https://github.com/jurecka/d3-zoom/commit/e4ee7bfe18ea7c1a9c7877ed34dc504f601259af

magicsunday commented 5 years ago

@mbostock Any chance to get this merged sometimes?

mariechatfield commented 5 years ago

I'd love to see this PR merged! In the meantime, here's a workaround I've written in our app code that manually calls the filter method:

const D3_TOUCH_PATCH_EVENTS = [
  "touchmove.zoom",
  "touchend.zoom touchcancel.zoom"
];

const _patchD3ZoomTouchEvents = ({ filter, selection }) => {
  D3_TOUCH_PATCH_EVENTS.map((eventName) => {
    const originalHandler = selection.on(eventName);

    if (!originalHandler) {
      return;
    }

    selection.on(eventName, () => {
      // Prevent original d3-zoom handler from calling if this event
      // *should* be filtered out. This is a bug in d3-zoom!
      // See https://github.com/d3/d3-zoom/pull/125
      if (!filter()) {
        return;
      }

      originalHandler.apply(d3.event.currentTarget, arguments);
    });
  });
};

const filter = () => { /* filter logic here */ };
const handleZoom = () => { /* zoom logic here */ };

const selection = d3.select("#myCoolElement");

const zoom = d3
  .zoom()
  .filter(filter)
  .on("zoom", handleZoom);

selection.call(zoom);

_patchD3ZoomTouchEvents({ filter, selection });
mbostock commented 5 years ago

Closing in favor of #169 as discussed in https://github.com/d3/d3-zoom/issues/124#issuecomment-390034133.