d3 / d3-selection

Transform the DOM by selecting elements and joining to data.

Home Page:https://d3js.org/d3-selection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

d3.pointer multitouch

Fil opened this issue · comments

(On branch two)

d3.pointer(TouchEvent) currently returns [NaN,NaN]; this can be fixed by adding at the top of src/pointer.js:

  if (event instanceof TouchEvent) event = event.touches[0];

This way we can call d3.pointer(event) to get a single point.

To access the multiple touches is still a bit complex:
[...event.touches].map(e => d3.pointer(e, event.currentTarget))

It might be nice to add d3.pointers(event[, node]), which would return an array of touches (for any event type, though only multitouch would return an array with more than one point).

demo: https://observablehq.com/d/4e6b3fcf97903e79

Ref: #191

Would be fixed by #246

This was intentional; you’re supposed to pass a Touch to d3.pointer, not a TouchEvent, to indicate which touch you care about.

The problem with d3.pointer (and before it, d3.mouse) automatically pulling out the first touch or the first changed touch is that it always leads to broken multitouch interaction. This behavior felt like a footgun, where clients thought they were supporting touch interaction by unifying a mousedown/touchstart or mousemove/touchmove handler, but in practice it would stop working as soon as more than one touch became active.

There is the question of migration and backwards-compatibility, though. If we make d3.pointer strict (as it is now), then it becomes more tedious for callers to adopt because they have to pass in the touch themselves. But since we’re changing the API anyway, we could introduce a deprecated method that implements the old, non-recommended behavior. Something like d3.anyPointer(event), with a note that people should switch to using d3.pointer. We could even call it d3.mouse(event, node = event.currentTarget), but it still wouldn’t be backwards-compatible because you need to pass in the event. For that matter, we could also retain equivalent versions of d3.touch(eventOrTouches, identifier, node = event.currentTarget) and d3.touches(eventOrTouches, node = event.currentTarget, …) to assist migration.

Thanks for the comments they clarified a lot of things. I don't think we want a new deprecated API, better work with what we have now, and help migrate to Pointer Events.