From 331874686a14b2c7029f9dc2a18ecf093652abe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 15 Jul 2020 15:29:47 +0200 Subject: [PATCH] introduces tapDistance (default 10 pixels) fixes #180 fixes #206 --- README.md | 6 +++++- src/zoom.js | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f784300a..fb7b4755 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ The propagation of all consumed events is [immediately stopped](https://dom.spec
³ Only applies immediately after some mouse-based gestures; see [*zoom*.clickDistance](#zoom_clickDistance).
⁴ Necessary to allow [click emulation](https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW7) on touch input; see [d3-drag#9](https://github.com/d3/d3-drag/issues/9).
⁵ Ignored if within 500ms of a touch gesture ending; assumes [click emulation](https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW7). -
⁶ Double-click and double-tap initiate a transition that emits start, zoom and end events. +
⁶ Double-click and double-tap initiate a transition that emits start, zoom and end events; see [*zoom*.tapDistance](#zoom_tapDistance)..
⁷ The first wheel event emits a start event; an end event is emitted when no wheel events are received for 150ms.
⁸ Ignored if already at the corresponding limit of the [scale extent](#zoom_scaleExtent). @@ -220,6 +220,10 @@ If *extent* is specified, sets the translate extent to the specified array of po If *distance* is specified, sets the maximum distance that the mouse can move between mousedown and mouseup that will trigger a subsequent click event. If at any point between mousedown and mouseup the mouse is greater than or equal to *distance* from its position on mousedown, the click event following mouseup will be suppressed. If *distance* is not specified, returns the current distance threshold, which defaults to zero. The distance threshold is measured in client coordinates ([*event*.clientX](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX) and [*event*.clientY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY)). +# zoom.tapDistance([distance]) · [Source](https://github.com/d3/d3-zoom/blob/master/src/zoom.js) + +If *distance* is specified, sets the maximum distance that a double-tap gesture can move between first touchstart and second touchend that will trigger a subsequent double-click event. If *distance* is not specified, returns the current distance threshold, which defaults to 10. The distance threshold is measured in client coordinates ([*event*.clientX](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX) and [*event*.clientY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY)). + # zoom.duration([duration]) · [Source](https://github.com/d3/d3-zoom/blob/master/src/zoom.js) If *duration* is specified, sets the duration for zoom transitions on double-click and double-tap to the specified number of milliseconds and returns the zoom behavior. If *duration* is not specified, returns the current duration, which defaults to 250 milliseconds. If the duration is not greater than zero, double-click and -tap trigger instantaneous changes to the zoom transform rather than initiating smooth transitions. diff --git a/src/zoom.js b/src/zoom.js index fa959025..4181717e 100644 --- a/src/zoom.js +++ b/src/zoom.js @@ -61,10 +61,12 @@ export default function() { interpolate = interpolateZoom, listeners = dispatch("start", "zoom", "end"), touchstarting, + touchfirst, touchending, touchDelay = 500, wheelDelay = 150, - clickDistance2 = 0; + clickDistance2 = 0, + tapDistance = 10; function zoom(selection) { selection @@ -331,7 +333,7 @@ export default function() { if (touchstarting) touchstarting = clearTimeout(touchstarting); if (started) { - if (g.taps < 2) touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); + if (g.taps < 2) touchfirst = p[0], touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); interrupt(this); g.start(); } @@ -344,8 +346,6 @@ export default function() { n = touches.length, i, t, p, l; noevent(event); - if (touchstarting) touchstarting = clearTimeout(touchstarting); - g.taps = 0; for (i = 0; i < n; ++i) { t = touches[i], p = pointer(t, this); if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; @@ -363,6 +363,7 @@ export default function() { } else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; else return; + g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent)); } @@ -386,8 +387,11 @@ export default function() { g.end(); // If this was a dbltap, reroute to the (optional) dblclick.zoom handler. if (g.taps === 2) { - var p = select(this).on("dblclick.zoom"); - if (p) p.apply(this, arguments); + t = pointer(t, this); + if (Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance) { + var p = select(this).on("dblclick.zoom"); + if (p) p.apply(this, arguments); + } } } } @@ -437,5 +441,9 @@ export default function() { return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); }; + zoom.tapDistance = function(_) { + return arguments.length ? (tapDistance = +_, zoom) : tapDistance; + }; + return zoom; }