Skip to content

Commit 120fb55

Browse files
committed
Fix issue with drag suppression for multitouch.
Due to the touchend listener being overwritten for every touchstart, two touchstart events would result in d3_event_dragSuppress being called twice, with only a single drag restore, meaning that a document's user-select style could be lost. This restructuring means that the first touchstart creates the closures for subsequent touchstart, touchmove and touchend events. A nice side-benefit is that fewer closures are created for multitouch.
1 parent 2fd0227 commit 120fb55

3 files changed

Lines changed: 70 additions & 49 deletions

File tree

d3.js

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,9 +1152,9 @@ d3 = function() {
11521152
return d3.rebind(drag, event, "on");
11531153
};
11541154
d3.behavior.zoom = function() {
1155-
var translate = [ 0, 0 ], translate0, scale = 1, scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", event = d3_eventDispatch(zoom, "zoom"), x0, x1, y0, y1, touchtime;
1155+
var translate = [ 0, 0 ], translate0, scale = 1, scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", touchstart = "touchstart.zoom", touchmove = "touchmove.zoom", touchend = "touchend.zoom", event = d3_eventDispatch(zoom, "zoom"), x0, x1, y0, y1;
11561156
function zoom() {
1157-
this.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on("touchstart.zoom", touchstarted);
1157+
this.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
11581158
}
11591159
zoom.translate = function(x) {
11601160
if (!arguments.length) return translate;
@@ -1232,22 +1232,28 @@ d3 = function() {
12321232
}
12331233
}
12341234
function touchstarted() {
1235-
var target = this, event_ = event.of(target, arguments), touches = d3.touches(target), locations = {}, distance0 = 0, scale0 = scale, now = Date.now(), touchmove = "touchmove.zoom", touchend = "touchend.zoom", w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null), dragRestore = d3_event_dragSuppress();
1236-
touches.forEach(function(t) {
1237-
locations[t.identifier] = location(t);
1238-
});
1239-
if (touches.length === 1) {
1240-
if (now - touchtime < 500) {
1241-
var p = touches[0], l = location(touches[0]);
1242-
scaleTo(scale * 2);
1243-
translateTo(p, l);
1244-
d3_eventPreventDefault();
1245-
dispatch(event_);
1235+
var target = this, event_ = event.of(target, arguments), locations, distance0 = 0, scale0, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(), touchtime;
1236+
started();
1237+
function started() {
1238+
var now = Date.now(), touches = d3.touches(target);
1239+
scale0 = scale;
1240+
locations = {};
1241+
touches.forEach(function(t) {
1242+
locations[t.identifier] = location(t);
1243+
});
1244+
if (touches.length === 1) {
1245+
if (now - touchtime < 500) {
1246+
var p = touches[0], l = location(touches[0]);
1247+
scaleTo(scale * 2);
1248+
translateTo(p, l);
1249+
d3_eventPreventDefault();
1250+
dispatch(event_);
1251+
}
1252+
touchtime = now;
1253+
} else if (touches.length > 1) {
1254+
var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
1255+
distance0 = dx * dx + dy * dy;
12461256
}
1247-
touchtime = now;
1248-
} else if (touches.length > 1) {
1249-
var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
1250-
distance0 = dx * dx + dy * dy;
12511257
}
12521258
function moved() {
12531259
var touches = d3.touches(target), p0 = touches[0], l0 = locations[p0.identifier];
@@ -1266,9 +1272,13 @@ d3 = function() {
12661272
dispatch(event_);
12671273
}
12681274
function ended() {
1269-
if (d3.event.touches.length) return;
1275+
if (d3.event.touches.length) {
1276+
touchtime = null;
1277+
started();
1278+
return;
1279+
}
12701280
w.on(touchmove, null).on(touchend, null);
1271-
t.on(mousedown, mousedowned);
1281+
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
12721282
dragRestore();
12731283
}
12741284
}

0 commit comments

Comments
 (0)