Comparing version 1.0.3 to 1.0.4
@@ -1,2 +0,2 @@ | ||
// https://d3js.org/d3-zoom/ Version 1.0.3. Copyright 2016 Mike Bostock. | ||
// https://d3js.org/d3-zoom/ Version 1.0.4. Copyright 2016 Mike Bostock. | ||
(function (global, factory) { | ||
@@ -6,435 +6,453 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-drag'), require('d3-interpolate'), require('d3-selection'), require('d3-transition')) : | ||
(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3)); | ||
}(this, function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict'; | ||
}(this, (function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict'; | ||
function constant(x) { | ||
return function() { | ||
return x; | ||
}; | ||
var constant = function(x) { | ||
return function() { | ||
return x; | ||
}; | ||
}; | ||
function ZoomEvent(target, type, transform) { | ||
this.target = target; | ||
this.type = type; | ||
this.transform = transform; | ||
} | ||
function Transform(k, x, y) { | ||
this.k = k; | ||
this.x = x; | ||
this.y = y; | ||
} | ||
Transform.prototype = { | ||
constructor: Transform, | ||
scale: function(k) { | ||
return k === 1 ? this : new Transform(this.k * k, this.x, this.y); | ||
}, | ||
translate: function(x, y) { | ||
return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); | ||
}, | ||
apply: function(point) { | ||
return [point[0] * this.k + this.x, point[1] * this.k + this.y]; | ||
}, | ||
applyX: function(x) { | ||
return x * this.k + this.x; | ||
}, | ||
applyY: function(y) { | ||
return y * this.k + this.y; | ||
}, | ||
invert: function(location) { | ||
return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; | ||
}, | ||
invertX: function(x) { | ||
return (x - this.x) / this.k; | ||
}, | ||
invertY: function(y) { | ||
return (y - this.y) / this.k; | ||
}, | ||
rescaleX: function(x) { | ||
return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); | ||
}, | ||
rescaleY: function(y) { | ||
return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); | ||
}, | ||
toString: function() { | ||
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; | ||
} | ||
}; | ||
function ZoomEvent(target, type, transform) { | ||
this.target = target; | ||
this.type = type; | ||
this.transform = transform; | ||
var identity = new Transform(1, 0, 0); | ||
transform.prototype = Transform.prototype; | ||
function transform(node) { | ||
return node.__zoom || identity; | ||
} | ||
function nopropagation() { | ||
d3Selection.event.stopImmediatePropagation(); | ||
} | ||
var noevent = function() { | ||
d3Selection.event.preventDefault(); | ||
d3Selection.event.stopImmediatePropagation(); | ||
}; | ||
// Ignore right-click, since that should open the context menu. | ||
function defaultFilter() { | ||
return !d3Selection.event.button; | ||
} | ||
function defaultExtent() { | ||
var e = this, w, h; | ||
if (e instanceof SVGElement) { | ||
e = e.ownerSVGElement || e; | ||
w = e.width.baseVal.value; | ||
h = e.height.baseVal.value; | ||
} else { | ||
w = e.clientWidth; | ||
h = e.clientHeight; | ||
} | ||
return [[0, 0], [w, h]]; | ||
} | ||
function Transform(k, x, y) { | ||
this.k = k; | ||
this.x = x; | ||
this.y = y; | ||
function defaultTransform() { | ||
return this.__zoom || identity; | ||
} | ||
var zoom = function() { | ||
var filter = defaultFilter, | ||
extent = defaultExtent, | ||
k0 = 0, | ||
k1 = Infinity, | ||
x0 = -k1, | ||
x1 = k1, | ||
y0 = x0, | ||
y1 = x1, | ||
duration = 250, | ||
interpolate = d3Interpolate.interpolateZoom, | ||
gestures = [], | ||
listeners = d3Dispatch.dispatch("start", "zoom", "end"), | ||
touchstarting, | ||
touchending, | ||
touchDelay = 500, | ||
wheelDelay = 150; | ||
function zoom(selection) { | ||
selection | ||
.on("wheel.zoom", wheeled) | ||
.on("mousedown.zoom", mousedowned) | ||
.on("dblclick.zoom", dblclicked) | ||
.on("touchstart.zoom", touchstarted) | ||
.on("touchmove.zoom", touchmoved) | ||
.on("touchend.zoom touchcancel.zoom", touchended) | ||
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") | ||
.property("__zoom", defaultTransform); | ||
} | ||
Transform.prototype = { | ||
constructor: Transform, | ||
scale: function(k) { | ||
return k === 1 ? this : new Transform(this.k * k, this.x, this.y); | ||
}, | ||
translate: function(x, y) { | ||
return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); | ||
}, | ||
apply: function(point) { | ||
return [point[0] * this.k + this.x, point[1] * this.k + this.y]; | ||
}, | ||
applyX: function(x) { | ||
return x * this.k + this.x; | ||
}, | ||
applyY: function(y) { | ||
return y * this.k + this.y; | ||
}, | ||
invert: function(location) { | ||
return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; | ||
}, | ||
invertX: function(x) { | ||
return (x - this.x) / this.k; | ||
}, | ||
invertY: function(y) { | ||
return (y - this.y) / this.k; | ||
}, | ||
rescaleX: function(x) { | ||
return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); | ||
}, | ||
rescaleY: function(y) { | ||
return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); | ||
}, | ||
toString: function() { | ||
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; | ||
zoom.transform = function(collection, transform) { | ||
var selection = collection.selection ? collection.selection() : collection; | ||
selection.property("__zoom", defaultTransform); | ||
if (collection !== selection) { | ||
schedule(collection, transform); | ||
} else { | ||
selection.interrupt().each(function() { | ||
gesture(this, arguments) | ||
.start() | ||
.zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) | ||
.end(); | ||
}); | ||
} | ||
}; | ||
var identity = new Transform(1, 0, 0); | ||
zoom.scaleBy = function(selection, k) { | ||
zoom.scaleTo(selection, function() { | ||
var k0 = this.__zoom.k, | ||
k1 = typeof k === "function" ? k.apply(this, arguments) : k; | ||
return k0 * k1; | ||
}); | ||
}; | ||
transform.prototype = Transform.prototype; | ||
zoom.scaleTo = function(selection, k) { | ||
zoom.transform(selection, function() { | ||
var e = extent.apply(this, arguments), | ||
t0 = this.__zoom, | ||
p0 = centroid(e), | ||
p1 = t0.invert(p0), | ||
k1 = typeof k === "function" ? k.apply(this, arguments) : k; | ||
return constrain(translate(scale(t0, k1), p0, p1), e); | ||
}); | ||
}; | ||
function transform(node) { | ||
return node.__zoom || identity; | ||
zoom.translateBy = function(selection, x, y) { | ||
zoom.transform(selection, function() { | ||
return constrain(this.__zoom.translate( | ||
typeof x === "function" ? x.apply(this, arguments) : x, | ||
typeof y === "function" ? y.apply(this, arguments) : y | ||
), extent.apply(this, arguments)); | ||
}); | ||
}; | ||
function scale(transform, k) { | ||
k = Math.max(k0, Math.min(k1, k)); | ||
return k === transform.k ? transform : new Transform(k, transform.x, transform.y); | ||
} | ||
function nopropagation() { | ||
d3Selection.event.stopImmediatePropagation(); | ||
function translate(transform, p0, p1) { | ||
var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; | ||
return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); | ||
} | ||
function noevent() { | ||
d3Selection.event.preventDefault(); | ||
d3Selection.event.stopImmediatePropagation(); | ||
function constrain(transform, extent) { | ||
var dx0 = transform.invertX(extent[0][0]) - x0, | ||
dx1 = transform.invertX(extent[1][0]) - x1, | ||
dy0 = transform.invertY(extent[0][1]) - y0, | ||
dy1 = transform.invertY(extent[1][1]) - y1; | ||
return transform.translate( | ||
dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), | ||
dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) | ||
); | ||
} | ||
// Ignore right-click, since that should open the context menu. | ||
function defaultFilter() { | ||
return !d3Selection.event.button; | ||
function centroid(extent) { | ||
return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; | ||
} | ||
function defaultExtent() { | ||
var e = this, w, h; | ||
if (e instanceof SVGElement) { | ||
e = e.ownerSVGElement || e; | ||
w = e.width.baseVal.value; | ||
h = e.height.baseVal.value; | ||
} else { | ||
w = e.clientWidth; | ||
h = e.clientHeight; | ||
function schedule(transition, transform, center) { | ||
transition | ||
.on("start.zoom", function() { gesture(this, arguments).start(); }) | ||
.on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) | ||
.tween("zoom", function() { | ||
var that = this, | ||
args = arguments, | ||
g = gesture(that, args), | ||
e = extent.apply(that, args), | ||
p = center || centroid(e), | ||
w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), | ||
a = that.__zoom, | ||
b = typeof transform === "function" ? transform.apply(that, args) : transform, | ||
i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); | ||
return function(t) { | ||
if (t === 1) t = b; // Avoid rounding error on end. | ||
else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } | ||
g.zoom(null, t); | ||
}; | ||
}); | ||
} | ||
function gesture(that, args) { | ||
for (var i = 0, n = gestures.length, g; i < n; ++i) { | ||
if ((g = gestures[i]).that === that) { | ||
return g; | ||
} | ||
} | ||
return [[0, 0], [w, h]]; | ||
return new Gesture(that, args); | ||
} | ||
function defaultTransform() { | ||
return this.__zoom || identity; | ||
function Gesture(that, args) { | ||
this.that = that; | ||
this.args = args; | ||
this.index = -1; | ||
this.active = 0; | ||
this.extent = extent.apply(that, args); | ||
} | ||
function zoom() { | ||
var filter = defaultFilter, | ||
extent = defaultExtent, | ||
k0 = 0, | ||
k1 = Infinity, | ||
x0 = -k1, | ||
x1 = k1, | ||
y0 = x0, | ||
y1 = x1, | ||
duration = 250, | ||
gestures = [], | ||
listeners = d3Dispatch.dispatch("start", "zoom", "end"), | ||
touchstarting, | ||
touchending, | ||
touchDelay = 500, | ||
wheelDelay = 150; | ||
function zoom(selection) { | ||
selection | ||
.on("wheel.zoom", wheeled) | ||
.on("mousedown.zoom", mousedowned) | ||
.on("dblclick.zoom", dblclicked) | ||
.on("touchstart.zoom", touchstarted) | ||
.on("touchmove.zoom", touchmoved) | ||
.on("touchend.zoom touchcancel.zoom", touchended) | ||
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") | ||
.property("__zoom", defaultTransform); | ||
Gesture.prototype = { | ||
start: function() { | ||
if (++this.active === 1) { | ||
this.index = gestures.push(this) - 1; | ||
this.emit("start"); | ||
} | ||
return this; | ||
}, | ||
zoom: function(key, transform) { | ||
if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); | ||
if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); | ||
if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); | ||
this.that.__zoom = transform; | ||
this.emit("zoom"); | ||
return this; | ||
}, | ||
end: function() { | ||
if (--this.active === 0) { | ||
gestures.splice(this.index, 1); | ||
this.index = -1; | ||
this.emit("end"); | ||
} | ||
return this; | ||
}, | ||
emit: function(type) { | ||
d3Selection.customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); | ||
} | ||
}; | ||
zoom.transform = function(collection, transform) { | ||
var selection = collection.selection ? collection.selection() : collection; | ||
selection.property("__zoom", defaultTransform); | ||
if (collection !== selection) { | ||
schedule(collection, transform); | ||
} else { | ||
selection.interrupt().each(function() { | ||
gesture(this, arguments) | ||
.start() | ||
.zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) | ||
.end(); | ||
}); | ||
function wheeled() { | ||
if (!filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
t = this.__zoom, | ||
k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -d3Selection.event.deltaY * (d3Selection.event.deltaMode ? 120 : 1) / 500))), | ||
p = d3Selection.mouse(this); | ||
// If the mouse is in the same location as before, reuse it. | ||
// If there were recent wheel events, reset the wheel idle timeout. | ||
if (g.wheel) { | ||
if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { | ||
g.mouse[1] = t.invert(g.mouse[0] = p); | ||
} | ||
}; | ||
clearTimeout(g.wheel); | ||
} | ||
zoom.scaleBy = function(selection, k) { | ||
zoom.scaleTo(selection, function() { | ||
var k0 = this.__zoom.k, | ||
k1 = typeof k === "function" ? k.apply(this, arguments) : k; | ||
return k0 * k1; | ||
}); | ||
}; | ||
// If this wheel event won’t trigger a transform change, ignore it. | ||
else if (t.k === k) return; | ||
zoom.scaleTo = function(selection, k) { | ||
zoom.transform(selection, function() { | ||
var e = extent.apply(this, arguments), | ||
t0 = this.__zoom, | ||
p0 = centroid(e), | ||
p1 = t0.invert(p0), | ||
k1 = typeof k === "function" ? k.apply(this, arguments) : k; | ||
return constrain(translate(scale(t0, k1), p0, p1), e); | ||
}); | ||
}; | ||
zoom.translateBy = function(selection, x, y) { | ||
zoom.transform(selection, function() { | ||
return constrain(this.__zoom.translate( | ||
typeof x === "function" ? x.apply(this, arguments) : x, | ||
typeof y === "function" ? y.apply(this, arguments) : y | ||
), extent.apply(this, arguments)); | ||
}); | ||
}; | ||
function scale(transform, k) { | ||
k = Math.max(k0, Math.min(k1, k)); | ||
return k === transform.k ? transform : new Transform(k, transform.x, transform.y); | ||
// Otherwise, capture the mouse point and location at the start. | ||
else { | ||
g.mouse = [p, t.invert(p)]; | ||
d3Transition.interrupt(this); | ||
g.start(); | ||
} | ||
function translate(transform, p0, p1) { | ||
var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; | ||
return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); | ||
} | ||
noevent(); | ||
g.wheel = setTimeout(wheelidled, wheelDelay); | ||
g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent)); | ||
function constrain(transform, extent) { | ||
var dx = Math.min(0, transform.invertX(extent[0][0]) - x0) || Math.max(0, transform.invertX(extent[1][0]) - x1), | ||
dy = Math.min(0, transform.invertY(extent[0][1]) - y0) || Math.max(0, transform.invertY(extent[1][1]) - y1); | ||
return dx || dy ? transform.translate(dx, dy) : transform; | ||
function wheelidled() { | ||
g.wheel = null; | ||
g.end(); | ||
} | ||
} | ||
function centroid(extent) { | ||
return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; | ||
} | ||
function mousedowned() { | ||
if (touchending || !filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
v = d3Selection.select(d3Selection.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), | ||
p = d3Selection.mouse(this); | ||
function schedule(transition, transform, center) { | ||
transition | ||
.on("start.zoom", function() { gesture(this, arguments).start(); }) | ||
.on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); }) | ||
.tween("zoom", function() { | ||
var that = this, | ||
args = arguments, | ||
g = gesture(that, args), | ||
e = extent.apply(that, args), | ||
p = center || centroid(e), | ||
w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), | ||
a = that.__zoom, | ||
b = typeof transform === "function" ? transform.apply(that, args) : transform, | ||
i = d3Interpolate.interpolateZoom(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); | ||
return function(t) { | ||
if (t === 1) t = b; // Avoid rounding error on end. | ||
else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } | ||
g.zoom(null, t); | ||
}; | ||
}); | ||
} | ||
d3Drag.dragDisable(d3Selection.event.view); | ||
nopropagation(); | ||
g.mouse = [p, this.__zoom.invert(p)]; | ||
d3Transition.interrupt(this); | ||
g.start(); | ||
function gesture(that, args) { | ||
for (var i = 0, n = gestures.length, g; i < n; ++i) { | ||
if ((g = gestures[i]).that === that) { | ||
return g; | ||
} | ||
} | ||
return new Gesture(that, args); | ||
function mousemoved() { | ||
noevent(); | ||
g.moved = true; | ||
g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3Selection.mouse(g.that), g.mouse[1]), g.extent)); | ||
} | ||
function Gesture(that, args) { | ||
this.that = that; | ||
this.args = args; | ||
this.index = -1; | ||
this.active = 0; | ||
this.extent = extent.apply(that, args); | ||
function mouseupped() { | ||
v.on("mousemove.zoom mouseup.zoom", null); | ||
d3Drag.dragEnable(d3Selection.event.view, g.moved); | ||
noevent(); | ||
g.end(); | ||
} | ||
} | ||
Gesture.prototype = { | ||
start: function() { | ||
if (++this.active === 1) { | ||
this.index = gestures.push(this) - 1; | ||
this.emit("start"); | ||
} | ||
return this; | ||
}, | ||
zoom: function(key, transform) { | ||
if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); | ||
if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); | ||
if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); | ||
this.that.__zoom = transform; | ||
this.emit("zoom"); | ||
return this; | ||
}, | ||
end: function() { | ||
if (--this.active === 0) { | ||
gestures.splice(this.index, 1); | ||
this.index = -1; | ||
this.emit("end"); | ||
} | ||
return this; | ||
}, | ||
emit: function(type) { | ||
d3Selection.customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]); | ||
} | ||
}; | ||
function dblclicked() { | ||
if (!filter.apply(this, arguments)) return; | ||
var t0 = this.__zoom, | ||
p0 = d3Selection.mouse(this), | ||
p1 = t0.invert(p0), | ||
k1 = t0.k * (d3Selection.event.shiftKey ? 0.5 : 2), | ||
t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments)); | ||
function wheeled() { | ||
if (!filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
t = this.__zoom, | ||
k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -d3Selection.event.deltaY * (d3Selection.event.deltaMode ? 120 : 1) / 500))), | ||
p = d3Selection.mouse(this); | ||
noevent(); | ||
if (duration > 0) d3Selection.select(this).transition().duration(duration).call(schedule, t1, p0); | ||
else d3Selection.select(this).call(zoom.transform, t1); | ||
} | ||
// If the mouse is in the same location as before, reuse it. | ||
// If there were recent wheel events, reset the wheel idle timeout. | ||
if (g.wheel) { | ||
if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { | ||
g.mouse[1] = t.invert(g.mouse[0] = p); | ||
} | ||
clearTimeout(g.wheel); | ||
} | ||
function touchstarted() { | ||
if (!filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t, p; | ||
// If this wheel event won’t trigger a transform change, ignore it. | ||
else if (t.k === k) return; | ||
nopropagation(); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i], p = d3Selection.touch(this, touches, t.identifier); | ||
p = [p, this.__zoom.invert(p), t.identifier]; | ||
if (!g.touch0) g.touch0 = p; | ||
else if (!g.touch1) g.touch1 = p; | ||
} | ||
// Otherwise, capture the mouse point and location at the start. | ||
else { | ||
g.mouse = [p, t.invert(p)]; | ||
d3Transition.interrupt(this); | ||
g.start(); | ||
} | ||
noevent(); | ||
g.wheel = setTimeout(wheelidled, wheelDelay); | ||
g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent)); | ||
function wheelidled() { | ||
g.wheel = null; | ||
// If this is a dbltap, reroute to the (optional) dblclick.zoom handler. | ||
if (touchstarting) { | ||
touchstarting = clearTimeout(touchstarting); | ||
if (!g.touch1) { | ||
g.end(); | ||
p = d3Selection.select(this).on("dblclick.zoom"); | ||
if (p) p.apply(this, arguments); | ||
return; | ||
} | ||
} | ||
function mousedowned() { | ||
if (touchending || !filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
v = d3Selection.select(d3Selection.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), | ||
p = d3Selection.mouse(this); | ||
d3Drag.dragDisable(d3Selection.event.view); | ||
nopropagation(); | ||
g.mouse = [p, this.__zoom.invert(p)]; | ||
if (d3Selection.event.touches.length === n) { | ||
touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); | ||
d3Transition.interrupt(this); | ||
g.start(); | ||
function mousemoved() { | ||
noevent(); | ||
g.moved = true; | ||
g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3Selection.mouse(g.that), g.mouse[1]), g.extent)); | ||
} | ||
function mouseupped() { | ||
v.on("mousemove.zoom mouseup.zoom", null); | ||
d3Drag.dragEnable(d3Selection.event.view, g.moved); | ||
noevent(); | ||
g.end(); | ||
} | ||
} | ||
} | ||
function dblclicked() { | ||
if (!filter.apply(this, arguments)) return; | ||
var t0 = this.__zoom, | ||
p0 = d3Selection.mouse(this), | ||
p1 = t0.invert(p0), | ||
k1 = t0.k * (d3Selection.event.shiftKey ? 0.5 : 2), | ||
t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments)); | ||
function touchmoved() { | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t, p, l; | ||
noevent(); | ||
if (duration > 0) d3Selection.select(this).transition().duration(duration).call(schedule, t1, p0); | ||
else d3Selection.select(this).call(zoom.transform, t1); | ||
noevent(); | ||
if (touchstarting) touchstarting = clearTimeout(touchstarting); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i], p = d3Selection.touch(this, touches, t.identifier); | ||
if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; | ||
else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; | ||
} | ||
function touchstarted() { | ||
if (!filter.apply(this, arguments)) return; | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t, p; | ||
nopropagation(); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i], p = d3Selection.touch(this, touches, t.identifier); | ||
p = [p, this.__zoom.invert(p), t.identifier]; | ||
if (!g.touch0) g.touch0 = p; | ||
else if (!g.touch1) g.touch1 = p; | ||
} | ||
if (touchstarting) { | ||
touchstarting = clearTimeout(touchstarting); | ||
if (!g.touch1) return g.end(), dblclicked.apply(this, arguments); | ||
} | ||
if (d3Selection.event.touches.length === n) { | ||
touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); | ||
d3Transition.interrupt(this); | ||
g.start(); | ||
} | ||
t = g.that.__zoom; | ||
if (g.touch1) { | ||
var p0 = g.touch0[0], l0 = g.touch0[1], | ||
p1 = g.touch1[0], l1 = g.touch1[1], | ||
dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, | ||
dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; | ||
t = scale(t, Math.sqrt(dp / dl)); | ||
p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; | ||
l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; | ||
} | ||
else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; | ||
else return; | ||
g.zoom("touch", constrain(translate(t, p, l), g.extent)); | ||
} | ||
function touchmoved() { | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t, p, l; | ||
function touchended() { | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t; | ||
noevent(); | ||
if (touchstarting) touchstarting = clearTimeout(touchstarting); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i], p = d3Selection.touch(this, touches, t.identifier); | ||
if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; | ||
else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; | ||
} | ||
t = g.that.__zoom; | ||
if (g.touch1) { | ||
var p0 = g.touch0[0], l0 = g.touch0[1], | ||
p1 = g.touch1[0], l1 = g.touch1[1], | ||
dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, | ||
dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; | ||
t = scale(t, Math.sqrt(dp / dl)); | ||
p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; | ||
l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; | ||
} | ||
else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; | ||
else return; | ||
g.zoom("touch", constrain(translate(t, p, l), g.extent)); | ||
nopropagation(); | ||
if (touchending) clearTimeout(touchending); | ||
touchending = setTimeout(function() { touchending = null; }, touchDelay); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i]; | ||
if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; | ||
else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; | ||
} | ||
if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; | ||
if (!g.touch0) g.end(); | ||
} | ||
function touchended() { | ||
var g = gesture(this, arguments), | ||
touches = d3Selection.event.changedTouches, | ||
n = touches.length, i, t; | ||
zoom.filter = function(_) { | ||
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), zoom) : filter; | ||
}; | ||
nopropagation(); | ||
if (touchending) clearTimeout(touchending); | ||
touchending = setTimeout(function() { touchending = null; }, touchDelay); | ||
for (i = 0; i < n; ++i) { | ||
t = touches[i]; | ||
if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; | ||
else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; | ||
} | ||
if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; | ||
if (!g.touch0) g.end(); | ||
} | ||
zoom.extent = function(_) { | ||
return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; | ||
}; | ||
zoom.filter = function(_) { | ||
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), zoom) : filter; | ||
}; | ||
zoom.scaleExtent = function(_) { | ||
return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1]; | ||
}; | ||
zoom.extent = function(_) { | ||
return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; | ||
}; | ||
zoom.translateExtent = function(_) { | ||
return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]]; | ||
}; | ||
zoom.scaleExtent = function(_) { | ||
return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1]; | ||
}; | ||
zoom.duration = function(_) { | ||
return arguments.length ? (duration = +_, zoom) : duration; | ||
}; | ||
zoom.translateExtent = function(_) { | ||
return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]]; | ||
}; | ||
zoom.interpolate = function(_) { | ||
return arguments.length ? (interpolate = _, zoom) : interpolate; | ||
}; | ||
zoom.duration = function(_) { | ||
return arguments.length ? (duration = +_, zoom) : duration; | ||
}; | ||
zoom.on = function() { | ||
var value = listeners.on.apply(listeners, arguments); | ||
return value === listeners ? zoom : value; | ||
}; | ||
zoom.on = function() { | ||
var value = listeners.on.apply(listeners, arguments); | ||
return value === listeners ? zoom : value; | ||
}; | ||
return zoom; | ||
}; | ||
return zoom; | ||
} | ||
exports.zoom = zoom; | ||
exports.zoomTransform = transform; | ||
exports.zoomIdentity = identity; | ||
exports.zoom = zoom; | ||
exports.zoomTransform = transform; | ||
exports.zoomIdentity = identity; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
})); | ||
}))); |
@@ -1,2 +0,2 @@ | ||
// https://d3js.org/d3-zoom/ Version 1.0.3. Copyright 2016 Mike Bostock. | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-dispatch"),require("d3-drag"),require("d3-interpolate"),require("d3-selection"),require("d3-transition")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-drag","d3-interpolate","d3-selection","d3-transition"],e):e(t.d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3)}(this,function(t,e,n,o,i,r){"use strict";function u(t){return function(){return t}}function h(t,e,n){this.target=t,this.type=e,this.transform=n}function s(t,e,n){this.k=t,this.x=e,this.y=n}function c(t){return t.__zoom||v}function a(){i.event.stopImmediatePropagation()}function f(){i.event.preventDefault(),i.event.stopImmediatePropagation()}function m(){return!i.event.button}function l(){var t,e,n=this;return n instanceof SVGElement?(n=n.ownerSVGElement||n,t=n.width.baseVal.value,e=n.height.baseVal.value):(t=n.clientWidth,e=n.clientHeight),[[0,0],[t,e]]}function p(){return this.__zoom||v}function d(){function t(t){t.on("wheel.zoom",x).on("mousedown.zoom",k).on("dblclick.zoom",w).on("touchstart.zoom",M).on("touchmove.zoom",T).on("touchend.zoom touchcancel.zoom",b).style("-webkit-tap-highlight-color","rgba(0,0,0,0)").property("__zoom",p)}function c(t,e){return e=Math.max(V,Math.min(I,e)),e===t.k?t:new s(e,t.x,t.y)}function d(t,e,n){var o=e[0]-n[0]*t.k,i=e[1]-n[1]*t.k;return o===t.x&&i===t.y?t:new s(t.k,o,i)}function v(t,e){var n=Math.min(0,t.invertX(e[0][0])-P)||Math.max(0,t.invertX(e[1][0])-S),o=Math.min(0,t.invertY(e[0][1])-j)||Math.max(0,t.invertY(e[1][1])-B);return n||o?t.translate(n,o):t}function y(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function z(t,e,n){t.on("start.zoom",function(){_(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){_(this,arguments).end()}).tween("zoom",function(){var t=this,i=arguments,r=_(t,i),u=X.apply(t,i),h=n||y(u),c=Math.max(u[1][0]-u[0][0],u[1][1]-u[0][1]),a=t.__zoom,f="function"==typeof e?e.apply(t,i):e,m=o.interpolateZoom(a.invert(h).concat(c/a.k),f.invert(h).concat(c/f.k));return function(t){if(1===t)t=f;else{var e=m(t),n=c/e[2];t=new s(n,h[0]-e[0]*n,h[1]-e[1]*n)}r.zoom(null,t)}})}function _(t,e){for(var n,o=0,i=G.length;o<i;++o)if((n=G[o]).that===t)return n;return new g(t,e)}function g(t,e){this.that=t,this.args=e,this.index=-1,this.active=0,this.extent=X.apply(t,e)}function x(){function t(){e.wheel=null,e.end()}if(E.apply(this,arguments)){var e=_(this,arguments),n=this.__zoom,o=Math.max(V,Math.min(I,n.k*Math.pow(2,-i.event.deltaY*(i.event.deltaMode?120:1)/500))),u=i.mouse(this);if(e.wheel)e.mouse[0][0]===u[0]&&e.mouse[0][1]===u[1]||(e.mouse[1]=n.invert(e.mouse[0]=u)),clearTimeout(e.wheel);else{if(n.k===o)return;e.mouse=[u,n.invert(u)],r.interrupt(this),e.start()}f(),e.wheel=setTimeout(t,O),e.zoom("mouse",v(d(c(n,o),e.mouse[0],e.mouse[1]),e.extent))}}function k(){function t(){f(),o.moved=!0,o.zoom("mouse",v(d(o.that.__zoom,o.mouse[0]=i.mouse(o.that),o.mouse[1]),o.extent))}function e(){u.on("mousemove.zoom mouseup.zoom",null),n.dragEnable(i.event.view,o.moved),f(),o.end()}if(!q&&E.apply(this,arguments)){var o=_(this,arguments),u=i.select(i.event.view).on("mousemove.zoom",t,!0).on("mouseup.zoom",e,!0),h=i.mouse(this);n.dragDisable(i.event.view),a(),o.mouse=[h,this.__zoom.invert(h)],r.interrupt(this),o.start()}}function w(){if(E.apply(this,arguments)){var e=this.__zoom,n=i.mouse(this),o=e.invert(n),r=e.k*(i.event.shiftKey?.5:2),u=v(d(c(e,r),n,o),X.apply(this,arguments));f(),D>0?i.select(this).transition().duration(D).call(z,u,n):i.select(this).call(t.transform,u)}}function M(){if(E.apply(this,arguments)){var t,e,n,o=_(this,arguments),u=i.event.changedTouches,h=u.length;for(a(),t=0;t<h;++t)e=u[t],n=i.touch(this,u,e.identifier),n=[n,this.__zoom.invert(n),e.identifier],o.touch0?o.touch1||(o.touch1=n):o.touch0=n;return Y&&(Y=clearTimeout(Y),!o.touch1)?(o.end(),w.apply(this,arguments)):void(i.event.touches.length===h&&(Y=setTimeout(function(){Y=null},K),r.interrupt(this),o.start()))}}function T(){var t,e,n,o,r=_(this,arguments),u=i.event.changedTouches,h=u.length;for(f(),Y&&(Y=clearTimeout(Y)),t=0;t<h;++t)e=u[t],n=i.touch(this,u,e.identifier),r.touch0&&r.touch0[2]===e.identifier?r.touch0[0]=n:r.touch1&&r.touch1[2]===e.identifier&&(r.touch1[0]=n);if(e=r.that.__zoom,r.touch1){var s=r.touch0[0],a=r.touch0[1],m=r.touch1[0],l=r.touch1[1],p=(p=m[0]-s[0])*p+(p=m[1]-s[1])*p,y=(y=l[0]-a[0])*y+(y=l[1]-a[1])*y;e=c(e,Math.sqrt(p/y)),n=[(s[0]+m[0])/2,(s[1]+m[1])/2],o=[(a[0]+l[0])/2,(a[1]+l[1])/2]}else{if(!r.touch0)return;n=r.touch0[0],o=r.touch0[1]}r.zoom("touch",v(d(e,n,o),r.extent))}function b(){var t,e,n=_(this,arguments),o=i.event.changedTouches,r=o.length;for(a(),q&&clearTimeout(q),q=setTimeout(function(){q=null},K),t=0;t<r;++t)e=o[t],n.touch0&&n.touch0[2]===e.identifier?delete n.touch0:n.touch1&&n.touch1[2]===e.identifier&&delete n.touch1;n.touch1&&!n.touch0&&(n.touch0=n.touch1,delete n.touch1),n.touch0||n.end()}var Y,q,E=m,X=l,V=0,I=1/0,P=-I,S=I,j=P,B=S,D=250,G=[],H=e.dispatch("start","zoom","end"),K=500,O=150;return t.transform=function(t,e){var n=t.selection?t.selection():t;n.property("__zoom",p),t!==n?z(t,e):n.interrupt().each(function(){_(this,arguments).start().zoom(null,"function"==typeof e?e.apply(this,arguments):e).end()})},t.scaleBy=function(e,n){t.scaleTo(e,function(){var t=this.__zoom.k,e="function"==typeof n?n.apply(this,arguments):n;return t*e})},t.scaleTo=function(e,n){t.transform(e,function(){var t=X.apply(this,arguments),e=this.__zoom,o=y(t),i=e.invert(o),r="function"==typeof n?n.apply(this,arguments):n;return v(d(c(e,r),o,i),t)})},t.translateBy=function(e,n,o){t.transform(e,function(){return v(this.__zoom.translate("function"==typeof n?n.apply(this,arguments):n,"function"==typeof o?o.apply(this,arguments):o),X.apply(this,arguments))})},g.prototype={start:function(){return 1===++this.active&&(this.index=G.push(this)-1,this.emit("start")),this},zoom:function(t,e){return this.mouse&&"mouse"!==t&&(this.mouse[1]=e.invert(this.mouse[0])),this.touch0&&"touch"!==t&&(this.touch0[1]=e.invert(this.touch0[0])),this.touch1&&"touch"!==t&&(this.touch1[1]=e.invert(this.touch1[0])),this.that.__zoom=e,this.emit("zoom"),this},end:function(){return 0===--this.active&&(G.splice(this.index,1),this.index=-1,this.emit("end")),this},emit:function(e){i.customEvent(new h(t,e,this.that.__zoom),H.apply,H,[e,this.that,this.args])}},t.filter=function(e){return arguments.length?(E="function"==typeof e?e:u(!!e),t):E},t.extent=function(e){return arguments.length?(X="function"==typeof e?e:u([[+e[0][0],+e[0][1]],[+e[1][0],+e[1][1]]]),t):X},t.scaleExtent=function(e){return arguments.length?(V=+e[0],I=+e[1],t):[V,I]},t.translateExtent=function(e){return arguments.length?(P=+e[0][0],S=+e[1][0],j=+e[0][1],B=+e[1][1],t):[[P,j],[S,B]]},t.duration=function(e){return arguments.length?(D=+e,t):D},t.on=function(){var e=H.on.apply(H,arguments);return e===H?t:e},t}s.prototype={constructor:s,scale:function(t){return 1===t?this:new s(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new s(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var v=new s(1,0,0);c.prototype=s.prototype,t.zoom=d,t.zoomTransform=c,t.zoomIdentity=v,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
// https://d3js.org/d3-zoom/ Version 1.0.4. Copyright 2016 Mike Bostock. | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-dispatch"),require("d3-drag"),require("d3-interpolate"),require("d3-selection"),require("d3-transition")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-drag","d3-interpolate","d3-selection","d3-transition"],e):e(t.d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3)}(this,function(t,e,n,o,i,r){"use strict";function u(t,e,n){this.target=t,this.type=e,this.transform=n}function h(t,e,n){this.k=t,this.x=e,this.y=n}function s(t){return t.__zoom||p}function c(){i.event.stopImmediatePropagation()}function a(){return!i.event.button}function f(){var t,e,n=this;return n instanceof SVGElement?(n=n.ownerSVGElement||n,t=n.width.baseVal.value,e=n.height.baseVal.value):(t=n.clientWidth,e=n.clientHeight),[[0,0],[t,e]]}function l(){return this.__zoom||p}var m=function(t){return function(){return t}};h.prototype={constructor:h,scale:function(t){return 1===t?this:new h(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new h(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var p=new h(1,0,0);s.prototype=h.prototype;var d=function(){i.event.preventDefault(),i.event.stopImmediatePropagation()},v=function(){function t(t){t.on("wheel.zoom",x).on("mousedown.zoom",k).on("dblclick.zoom",w).on("touchstart.zoom",M).on("touchmove.zoom",T).on("touchend.zoom touchcancel.zoom",b).style("-webkit-tap-highlight-color","rgba(0,0,0,0)").property("__zoom",l)}function s(t,e){return e=Math.max(V,Math.min(I,e)),e===t.k?t:new h(e,t.x,t.y)}function p(t,e,n){var o=e[0]-n[0]*t.k,i=e[1]-n[1]*t.k;return o===t.x&&i===t.y?t:new h(t.k,o,i)}function v(t,e){var n=t.invertX(e[0][0])-P,o=t.invertX(e[1][0])-S,i=t.invertY(e[0][1])-j,r=t.invertY(e[1][1])-B;return t.translate(o>n?(n+o)/2:Math.min(0,n)||Math.max(0,o),r>i?(i+r)/2:Math.min(0,i)||Math.max(0,r))}function y(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function z(t,e,n){t.on("start.zoom",function(){_(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){_(this,arguments).end()}).tween("zoom",function(){var t=this,o=arguments,i=_(t,o),r=X.apply(t,o),u=n||y(r),s=Math.max(r[1][0]-r[0][0],r[1][1]-r[0][1]),c=t.__zoom,a="function"==typeof e?e.apply(t,o):e,f=G(c.invert(u).concat(s/c.k),a.invert(u).concat(s/a.k));return function(t){if(1===t)t=a;else{var e=f(t),n=s/e[2];t=new h(n,u[0]-e[0]*n,u[1]-e[1]*n)}i.zoom(null,t)}})}function _(t,e){for(var n,o=0,i=H.length;o<i;++o)if((n=H[o]).that===t)return n;return new g(t,e)}function g(t,e){this.that=t,this.args=e,this.index=-1,this.active=0,this.extent=X.apply(t,e)}function x(){function t(){e.wheel=null,e.end()}if(E.apply(this,arguments)){var e=_(this,arguments),n=this.__zoom,o=Math.max(V,Math.min(I,n.k*Math.pow(2,-i.event.deltaY*(i.event.deltaMode?120:1)/500))),u=i.mouse(this);if(e.wheel)e.mouse[0][0]===u[0]&&e.mouse[0][1]===u[1]||(e.mouse[1]=n.invert(e.mouse[0]=u)),clearTimeout(e.wheel);else{if(n.k===o)return;e.mouse=[u,n.invert(u)],r.interrupt(this),e.start()}d(),e.wheel=setTimeout(t,W),e.zoom("mouse",v(p(s(n,o),e.mouse[0],e.mouse[1]),e.extent))}}function k(){function t(){d(),o.moved=!0,o.zoom("mouse",v(p(o.that.__zoom,o.mouse[0]=i.mouse(o.that),o.mouse[1]),o.extent))}function e(){u.on("mousemove.zoom mouseup.zoom",null),n.dragEnable(i.event.view,o.moved),d(),o.end()}if(!q&&E.apply(this,arguments)){var o=_(this,arguments),u=i.select(i.event.view).on("mousemove.zoom",t,!0).on("mouseup.zoom",e,!0),h=i.mouse(this);n.dragDisable(i.event.view),c(),o.mouse=[h,this.__zoom.invert(h)],r.interrupt(this),o.start()}}function w(){if(E.apply(this,arguments)){var e=this.__zoom,n=i.mouse(this),o=e.invert(n),r=e.k*(i.event.shiftKey?.5:2),u=v(p(s(e,r),n,o),X.apply(this,arguments));d(),D>0?i.select(this).transition().duration(D).call(z,u,n):i.select(this).call(t.transform,u)}}function M(){if(E.apply(this,arguments)){var t,e,n,o=_(this,arguments),u=i.event.changedTouches,h=u.length;for(c(),t=0;t<h;++t)e=u[t],n=i.touch(this,u,e.identifier),n=[n,this.__zoom.invert(n),e.identifier],o.touch0?o.touch1||(o.touch1=n):o.touch0=n;return Y&&(Y=clearTimeout(Y),!o.touch1)?(o.end(),n=i.select(this).on("dblclick.zoom"),void(n&&n.apply(this,arguments))):void(i.event.touches.length===h&&(Y=setTimeout(function(){Y=null},O),r.interrupt(this),o.start()))}}function T(){var t,e,n,o,r=_(this,arguments),u=i.event.changedTouches,h=u.length;for(d(),Y&&(Y=clearTimeout(Y)),t=0;t<h;++t)e=u[t],n=i.touch(this,u,e.identifier),r.touch0&&r.touch0[2]===e.identifier?r.touch0[0]=n:r.touch1&&r.touch1[2]===e.identifier&&(r.touch1[0]=n);if(e=r.that.__zoom,r.touch1){var c=r.touch0[0],a=r.touch0[1],f=r.touch1[0],l=r.touch1[1],m=(m=f[0]-c[0])*m+(m=f[1]-c[1])*m,y=(y=l[0]-a[0])*y+(y=l[1]-a[1])*y;e=s(e,Math.sqrt(m/y)),n=[(c[0]+f[0])/2,(c[1]+f[1])/2],o=[(a[0]+l[0])/2,(a[1]+l[1])/2]}else{if(!r.touch0)return;n=r.touch0[0],o=r.touch0[1]}r.zoom("touch",v(p(e,n,o),r.extent))}function b(){var t,e,n=_(this,arguments),o=i.event.changedTouches,r=o.length;for(c(),q&&clearTimeout(q),q=setTimeout(function(){q=null},O),t=0;t<r;++t)e=o[t],n.touch0&&n.touch0[2]===e.identifier?delete n.touch0:n.touch1&&n.touch1[2]===e.identifier&&delete n.touch1;n.touch1&&!n.touch0&&(n.touch0=n.touch1,delete n.touch1),n.touch0||n.end()}var Y,q,E=a,X=f,V=0,I=1/0,P=-I,S=I,j=P,B=S,D=250,G=o.interpolateZoom,H=[],K=e.dispatch("start","zoom","end"),O=500,W=150;return t.transform=function(t,e){var n=t.selection?t.selection():t;n.property("__zoom",l),t!==n?z(t,e):n.interrupt().each(function(){_(this,arguments).start().zoom(null,"function"==typeof e?e.apply(this,arguments):e).end()})},t.scaleBy=function(e,n){t.scaleTo(e,function(){var t=this.__zoom.k,e="function"==typeof n?n.apply(this,arguments):n;return t*e})},t.scaleTo=function(e,n){t.transform(e,function(){var t=X.apply(this,arguments),e=this.__zoom,o=y(t),i=e.invert(o),r="function"==typeof n?n.apply(this,arguments):n;return v(p(s(e,r),o,i),t)})},t.translateBy=function(e,n,o){t.transform(e,function(){return v(this.__zoom.translate("function"==typeof n?n.apply(this,arguments):n,"function"==typeof o?o.apply(this,arguments):o),X.apply(this,arguments))})},g.prototype={start:function(){return 1===++this.active&&(this.index=H.push(this)-1,this.emit("start")),this},zoom:function(t,e){return this.mouse&&"mouse"!==t&&(this.mouse[1]=e.invert(this.mouse[0])),this.touch0&&"touch"!==t&&(this.touch0[1]=e.invert(this.touch0[0])),this.touch1&&"touch"!==t&&(this.touch1[1]=e.invert(this.touch1[0])),this.that.__zoom=e,this.emit("zoom"),this},end:function(){return 0===--this.active&&(H.splice(this.index,1),this.index=-1,this.emit("end")),this},emit:function(e){i.customEvent(new u(t,e,this.that.__zoom),K.apply,K,[e,this.that,this.args])}},t.filter=function(e){return arguments.length?(E="function"==typeof e?e:m(!!e),t):E},t.extent=function(e){return arguments.length?(X="function"==typeof e?e:m([[+e[0][0],+e[0][1]],[+e[1][0],+e[1][1]]]),t):X},t.scaleExtent=function(e){return arguments.length?(V=+e[0],I=+e[1],t):[V,I]},t.translateExtent=function(e){return arguments.length?(P=+e[0][0],S=+e[1][0],j=+e[0][1],B=+e[1][1],t):[[P,j],[S,B]]},t.duration=function(e){return arguments.length?(D=+e,t):D},t.interpolate=function(e){return arguments.length?(G=e,t):G},t.on=function(){var e=K.on.apply(K,arguments);return e===K?t:e},t};t.zoom=v,t.zoomTransform=s,t.zoomIdentity=p,Object.defineProperty(t,"__esModule",{value:!0})}); |
{ | ||
"name": "d3-zoom", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "Pan and zoom SVG, HTML or Canvas using mouse or touch input.", | ||
@@ -39,5 +39,5 @@ "keywords": [ | ||
"devDependencies": { | ||
"eslint": "2", | ||
"eslint": "3", | ||
"package-preamble": "0.0", | ||
"rollup": "0.34", | ||
"rollup": "0.36", | ||
"tape": "4", | ||
@@ -44,0 +44,0 @@ "uglify-js": "2" |
@@ -13,2 +13,6 @@ # d3-zoom | ||
The zoom behavior can be combined with other behaviors, such as [d3-drag](https://github.com/d3/d3-drag) for dragging. | ||
[<img alt="Drag & Zoom II" src="https://raw.githubusercontent.com/d3/d3-zoom/master/img/dots.png" width="420" height="219">](http://bl.ocks.org/mbostock/3127661b6f13f9316be745e77fdfb084) | ||
The zoom behavior can be controlled programmatically using [*zoom*.transform](#zoom_transform), allowing you to implement user interface controls which drive the display or to stage animated tours through your data. Smooth zoom transitions are based on [“Smooth and efficient zooming and panning”](http://www.win.tue.nl/~vanwijk/zoompan.pdf) by Jarke J. van Wijk and Wim A.A. Nuij. | ||
@@ -18,2 +22,4 @@ | ||
See also [d3-tile](https://github.com/d3/d3-tile) for examples panning and zooming maps. | ||
## Installing | ||
@@ -55,3 +61,3 @@ | ||
| dblclick | selection | *multiple*⁶ | yes | | ||
| wheel | selection | zoom⁷ | yes | | ||
| wheel⁸ | selection | zoom⁷ | yes | | ||
| touchstart | selection | *multiple*⁶ | no⁴ | | ||
@@ -71,8 +77,9 @@ | touchmove | selection | zoom | yes | | ||
<br>⁷ The first wheel event emits a start event; an end event is emitted when no wheel events are received for 150ms. | ||
<br>⁸ Ignored if already at the corresponding limit of the [scale extent](#zoom_scaleExtent). | ||
<a href="#zoom" name="zoom">#</a> d3.<b>zoom</b>() | ||
<a href="#zoom" name="zoom">#</a> d3.<b>zoom</b>() [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js "Source") | ||
Creates a new zoom behavior. The returned behavior, [*zoom*](#_drag), is both an object and a function, and is typically applied to selected elements via [*selection*.call](https://github.com/d3/d3-selection#selection_call). | ||
<a href="#_zoom" name="_zoom">#</a> <i>zoom</i>(<i>selection</i>) | ||
<a href="#_zoom" name="_zoom">#</a> <i>zoom</i>(<i>selection</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L51 "Source") | ||
@@ -93,5 +100,5 @@ Applies this zoom behavior to the specified [*selection*](https://github.com/d3/d3-selection), binding the necessary event listeners to allow panning and zooming, and initializing the [zoom transform](#zoom-transforms) on each selected element to the identity transform if not already defined. This function is typically not invoked directly, and is instead invoked via [*selection*.call](https://github.com/d3/d3-selection#selection_call). For example, to instantiate a zoom behavior and apply it to a selection: | ||
<a href="#zoom_transform" name="zoom_transform">#</a> <i>zoom</i>.<b>transform</b>(<i>selection</i>, <i>transform</i>) | ||
<a href="#zoom_transform" name="zoom_transform">#</a> <i>zoom</i>.<b>transform</b>(<i>selection</i>, <i>transform</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L63 "Source") | ||
If *selection* is a selection, sets the [current zoom transform](#zoomTransform) of the selected elements to the specifed *transform*, instantaneously emitting start, zoom and end [events](#zoom-events). If *selection* is a transition, defines a “zoom” tween to the specified *transform* using [d3.interpolateZoom](https://github.com/d3/d3-interpolate#interpolateZoom), emitting a start event when the transition starts, zoom events for each tick of the transition, and then an end event when the transition ends (or is interrupted). The *transform* may be specified either as a [zoom transform](#zoom-transforms) or as a function that returns a zoom transform. If a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
If *selection* is a selection, sets the [current zoom transform](#zoomTransform) of the selected elements to the specified *transform*, instantaneously emitting start, zoom and end [events](#zoom-events). If *selection* is a transition, defines a “zoom” tween to the specified *transform* using [d3.interpolateZoom](https://github.com/d3/d3-interpolate#interpolateZoom), emitting a start event when the transition starts, zoom events for each tick of the transition, and then an end event when the transition ends (or is interrupted). The *transform* may be specified either as a [zoom transform](#zoom-transforms) or as a function that returns a zoom transform. If a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
@@ -112,15 +119,15 @@ This function is typically not invoked directly, and is instead invoked via [*selection*.call](https://github.com/d3/d3-selection#selection_call) or [*transition*.call](https://github.com/d3/d3-transition#transition_call). For example, to reset the zoom transform to the [identity transform](#zoomIdentity) instantaneously: | ||
<a href="#zoom_translateBy" name="zoom_translateBy">#</a> <i>zoom</i>.<b>translateBy</b>(<i>selection</i>, <i>x</i>, <i>y</i>) | ||
<a href="#zoom_translateBy" name="zoom_translateBy">#</a> <i>zoom</i>.<b>translateBy</b>(<i>selection</i>, <i>x</i>, <i>y</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L97 "Source") | ||
If *selection* is a selection, [translates](#transform_translate) the [current zoom transform](#zoomTransform) of the selected elements by *x* and *y*, such that the new *t<sub>x1</sub>* = *t<sub>x0</sub>* + *k* × *x* and *t<sub>y1</sub>* = *t<sub>y0</sub>* + *k* × *y*. If *selection* is a transition, defines a “zoom” tween translating the current transform. This method is a convenience method for [*zoom*.transform](#zoom_transform). The *x* and *y* translation amounts may be specified either as numbers or as functions that returns numbers. If a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
<a href="#zoom_scaleBy" name="zoom_scaleBy">#</a> <i>zoom</i>.<b>scaleBy</b>(<i>selection</i>, <i>k</i>) | ||
<a href="#zoom_scaleBy" name="zoom_scaleBy">#</a> <i>zoom</i>.<b>scaleBy</b>(<i>selection</i>, <i>k</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L78 "Source") | ||
If *selection* is a selection, [scales](#transform_scale) the [current zoom transform](#zoomTransform) of the selected elements by *k*, such that the new *k₁* = *k₀* × *k*. If *selection* is a transition, defines a “zoom” tween translating the current transform. This method is a convenience method for [*zoom*.transform](#zoom_transform). The *k* scale factor may be specified either as numbers or as functions that returns numbers. If a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
<a href="#zoom_scaleTo" name="zoom_scaleTo">#</a> <i>zoom</i>.<b>scaleTo</b>(<i>selection</i>, <i>k</i>) | ||
<a href="#zoom_scaleTo" name="zoom_scaleTo">#</a> <i>zoom</i>.<b>scaleTo</b>(<i>selection</i>, <i>k</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L86 "Source") | ||
If *selection* is a selection, [scales](#transform_scale) the [current zoom transform](#zoomTransform) of the selected elements to *k*, such that the new *k₁* = *k*. If *selection* is a transition, defines a “zoom” tween translating the current transform. This method is a convenience method for [*zoom*.transform](#zoom_transform). The *k* scale factor may be specified either as numbers or as functions that returns numbers. If a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
<a href="#zoom_filter" name="zoom_filter">#</a> <i>zoom</i>.<b>filter</b>([<i>filter</i>]) | ||
<a href="#zoom_filter" name="zoom_filter">#</a> <i>zoom</i>.<b>filter</b>([<i>filter</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L350 "Source") | ||
@@ -137,22 +144,44 @@ If *filter* is specified, sets the filter to the specified function and returns the zoom behavior. If *filter* is not specified, returns the current filter, which defaults to: | ||
<a href="#zoom_extent" name="zoom_extent">#</a> <i>zoom</i>.<b>extent</b>([<i>extent</i>]) | ||
<a href="#zoom_extent" name="zoom_extent">#</a> <i>zoom</i>.<b>extent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L354 "Source") | ||
If *extent* is specified, sets the viewport extent to the specified array of points [[*x0*, *y0*], [*x1*, *y1*]], where [*x0*, *y0*] is the top-left corner of the viewport and [*x1*, *y1*] is the bottom-right corner of the viewport, and returns this zoom behavior. The *extent* may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. If *extent* is not specified, returns the current extent accessor, which defaults to [[0, 0], [*width*, *height*]] where *width* is the [client width](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) of the element and *height* is its [client height](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight); for SVG elements, the nearest ancestor SVG element’s [width](https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute) and [height](https://www.w3.org/TR/SVG/struct.html#SVGElementHeightAttribute) is used. | ||
If *extent* is specified, sets the viewport extent to the specified array of points [[*x0*, *y0*], [*x1*, *y1*]], where [*x0*, *y0*] is the top-left corner of the viewport and [*x1*, *y1*] is the bottom-right corner of the viewport, and returns this zoom behavior. The *extent* may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
If *extent* is not specified, returns the current extent accessor, which defaults to [[0, 0], [*width*, *height*]] where *width* is the [client width](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) of the element and *height* is its [client height](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight); for SVG elements, the nearest ancestor SVG element’s [width](https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute) and [height](https://www.w3.org/TR/SVG/struct.html#SVGElementHeightAttribute) is used. In this case, the owner SVG element must have defined [width](https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute) and [height](https://www.w3.org/TR/SVG/struct.html#SVGElementHeightAttribute) attributes rather than (for example) relying on CSS properties or the viewBox attribute; SVG provides no programmatic method for retrieving the [initial viewport size](https://www.w3.org/TR/SVG/coords.html#ViewportSpace). Alternatively, consider using [*element*.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). (In Firefox, [*element*.clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) and [*element*.clientHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight) is zero for SVG elements!) | ||
The viewport extent affects several functions: the center of the viewport remains fixed during changes by [*zoom*.scaleBy](#zoom_scaleBy) and [*zoom*.scaleTo](#zoom_scaleTo); the viewport center and dimensions affect the path chosen by [d3.interpolateZoom](https://github.com/d3/d3-interpolate#interpolateZoom); and the viewport extent is needed to enforce the optional [translate extent](#zoom_translateExtent.) | ||
<a href="#zoom_scaleExtent" name="zoom_scaleExtent">#</a> <i>zoom</i>.<b>scaleExtent</b>([<i>extent</i>]) | ||
<a href="#zoom_scaleExtent" name="zoom_scaleExtent">#</a> <i>zoom</i>.<b>scaleExtent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L358 "Source") | ||
If *extent* is specified, sets the scale extent to the specified array of numbers [*k0*, *k1*] where *k0* is the minimum allowed scale factor and *k1* is the maximum allowed scale factor, and returns this zoom behavior. If *extent* is not specified, returns the current scale extent, which defaults to [0, ∞]. The scale extent restricts zooming in and out. It is enforced on interaction and when using [*zoom*.scaleBy](#zoom_scaleBy), [*zoom*.scaleTo](#zoom_scaleTo) and [*zoom*.translateBy](#zoom_translateBy); however, it is not enforced when using [*zoom*.transform](#zoom_transform) to set the transform explicitly. | ||
<a href="#zoom_translateExtent" name="zoom_translateExtent">#</a> <i>zoom</i>.<b>translateExtent</b>([<i>extent</i>]) | ||
If the user tries to zoom by wheeling when already at the corresponding limit of the scale extent, the wheel events will be ignored and not initiate a zoom gesture. This allows the user to scroll down past a zoomable area after zooming in, or to scroll up after zooming out. If you would prefer to always prevent scrolling on wheel input regardless of the scale extent, register a wheel event listener to prevent the browser default behavior: | ||
```js | ||
selection | ||
.call(zoom) | ||
.on("wheel", function() { d3.event.preventDefault(); }); | ||
``` | ||
<a href="#zoom_translateExtent" name="zoom_translateExtent">#</a> <i>zoom</i>.<b>translateExtent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L362 "Source") | ||
If *extent* is specified, sets the translate extent to the specified array of points [[*x0*, *y0*], [*x1*, *y1*]], where [*x0*, *y0*] is the top-left corner of the world and [*x1*, *y1*] is the bottom-right corner of the world, and returns this zoom behavior. If *extent* is not specified, returns the current translate extent, which defaults to [[-∞, -∞], [+∞, +∞]]. The translate extent restricts panning, and may cause translation on zoom out. It is enforced on interaction and when using [*zoom*.scaleBy](#zoom_scaleBy), [*zoom*.scaleTo](#zoom_scaleTo) and [*zoom*.translateBy](#zoom_translateBy); however, it is not enforced when using [*zoom*.transform](#zoom_transform) to set the transform explicitly. | ||
<a href="#zoom_duration" name="zoom_duration">#</a> <i>zoom</i>.<b>duration</b>([<i>duration</i>]) | ||
<a href="#zoom_duration" name="zoom_duration">#</a> <i>zoom</i>.<b>duration</b>([<i>duration</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L366 "Source") | ||
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. | ||
<a href="#zoom_on" name="zoom_on">#</a> <i>zoom</i>.<b>on</b>(<i>typenames</i>[, <i>listener</i>]) | ||
To disable double-click and double-tap transitions, you can remove the zoom behavior’s dblclick event listener after applying the zoom behavior to the selection: | ||
```js | ||
selection | ||
.call(zoom) | ||
.on("dblclick.zoom", null); | ||
``` | ||
<a href="#zoom_interpolate" name="zoom_interpolate">#</a> <i>zoom</i>.<b>interpolate</b>([<i>interpolate</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L370 "Source") | ||
If *interpolate* is specified, sets the interpolation factory for zoom transitions to the specified function. If *interpolate* is not specified, returns the current interpolation factory, which defaults to [d3.interpolateZoom](https://github.com/d3/d3-interpolate#interpolateZoom) to implement smooth zooming. To apply direct interpolation between two views, try [d3.interpolate](https://github.com/d3/d3-interpolate#interpolate) instead. | ||
<a href="#zoom_on" name="zoom_on">#</a> <i>zoom</i>.<b>on</b>(<i>typenames</i>[, <i>listener</i>]) [<>](https://github.com/d3/d3-zoom/blob/master/src/zoom.js#L374 "Source") | ||
If *listener* is specified, sets the event *listener* for the specified *typenames* and returns the zoom behavior. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If *listener* is null, removes the current event listeners for the specified *typenames*, if any. If *listener* is not specified, returns the first currently-assigned listener matching the specified *typenames*, if any. When a specified event is dispatched, each *listener* will be invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
@@ -183,6 +212,18 @@ | ||
<a href="#zoomTransform" name="zoomTransform">#</a> d3.<b>zoomTransform</b>(<i>node</i>) | ||
<a href="#zoomTransform" name="zoomTransform">#</a> d3.<b>zoomTransform</b>(<i>node</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js "Source") | ||
Returns the current transform for the specified *node*. Internally, an element’s transform is stored as *element*.\_\_zoom; however, you should use this method rather than accessing it directly. If the given *node* has no defined transform, returns the [identity transformation](#zoomIdentity). The returned transform represents a two-dimensional [transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations) of the form: | ||
Returns the current transform for the specified *node*. Note that *node* should typically be a DOM element, not a *selection*. (A selection may consist of multiple nodes, in different states, and this function only returns a single transform.) If you have a selection, call [*selection*.node](https://github.com/d3/d3-selection#selection_node) first: | ||
```js | ||
var transform = d3.zoomTransform(selection.node()); | ||
``` | ||
In the context of an [event listener](https://github.com/d3/d3-selection#selection_on), the *node* is typically the element that received the input event (which should be equal to [*event*.transform](#zoom-events)), *this*: | ||
```js | ||
var transform = d3.zoomTransform(this); | ||
``` | ||
Internally, an element’s transform is stored as *element*.\_\_zoom; however, you should use this method rather than accessing it directly. If the given *node* has no defined transform, returns the [identity transformation](#zoomIdentity). The returned transform represents a two-dimensional [transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations) of the form: | ||
*k* 0 *t<sub>x</sub>* | ||
@@ -231,35 +272,35 @@ <br>0 *k* *t<sub>y</sub>* | ||
<a href="#transform_scale" name="transform_scale">#</a> <i>transform</i>.<b>scale</b>(<i>k</i>) | ||
<a href="#transform_scale" name="transform_scale">#</a> <i>transform</i>.<b>scale</b>(<i>k</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L9 "Source") | ||
Returns a transform whose scale *k₁* is equal to *k₀* × *k*, where *k₀* is this transform’s scale. | ||
<a href="#transform_translate" name="transform_translate">#</a> <i>transform</i>.<b>translate</b>(<i>x</i>, <i>y</i>) | ||
<a href="#transform_translate" name="transform_translate">#</a> <i>transform</i>.<b>translate</b>(<i>x</i>, <i>y</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L12 "Source") | ||
Returns a transform whose translation *t<sub>x1</sub>* and *t<sub>y1</sub>* is equal to *t<sub>x0</sub>* + *x* and *t<sub>y0</sub>* + *y*, where *t<sub>x0</sub>* and *t<sub>y0</sub>* is this transform’s translation. | ||
<a href="#transform_apply" name="transform_apply">#</a> <i>transform</i>.<b>apply</b>(<i>point</i>) | ||
<a href="#transform_apply" name="transform_apply">#</a> <i>transform</i>.<b>apply</b>(<i>point</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L15 "Source") | ||
Returns the transformation of the specified *point* which is a two-element array of numbers [*x*, *y*]. The returned point is equal to [*x* × *k* + *t<sub>x</sub>*, *y* × *k* + *t<sub>y</sub>*]. | ||
<a href="#transform_applyX" name="transform_applyX">#</a> <i>transform</i>.<b>applyX</b>(<i>x</i>) | ||
<a href="#transform_applyX" name="transform_applyX">#</a> <i>transform</i>.<b>applyX</b>(<i>x</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L18 "Source") | ||
Returns the transformation of the specified *x*-coordinate, *x* × *k* + *t<sub>x</sub>*. | ||
<a href="#transform_applyY" name="transform_applyY">#</a> <i>transform</i>.<b>applyY</b>(<i>y</i>) | ||
<a href="#transform_applyY" name="transform_applyY">#</a> <i>transform</i>.<b>applyY</b>(<i>y</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L21 "Source") | ||
Returns the transformation of the specified *y*-coordinate, *y* × *k* + *t<sub>y</sub>*. | ||
<a href="#transform_invert" name="transform_invert">#</a> <i>transform</i>.<b>invert</b>(<i>point</i>) | ||
<a href="#transform_invert" name="transform_invert">#</a> <i>transform</i>.<b>invert</b>(<i>point</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L24 "Source") | ||
Returns the inverse transformation of the specified *point* which is a two-element array of numbers [*x*, *y*]. The returned point is equal to [(*x* - *t<sub>x</sub>*) / *k*, (*y* - *t<sub>y</sub>*) / *k*]. | ||
<a href="#transform_invertX" name="transform_invertX">#</a> <i>transform</i>.<b>invertX</b>(<i>x</i>) | ||
<a href="#transform_invertX" name="transform_invertX">#</a> <i>transform</i>.<b>invertX</b>(<i>x</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L27 "Source") | ||
Returns the inverse transformation of the specified *x*-coordinate, (*x* - *t<sub>x</sub>*) / *k*. | ||
<a href="#transform_invertY" name="transform_invertY">#</a> <i>transform</i>.<b>invertY</b>(<i>y</i>) | ||
<a href="#transform_invertY" name="transform_invertY">#</a> <i>transform</i>.<b>invertY</b>(<i>y</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L30 "Source") | ||
Returns the inverse transformation of the specified *y*-coordinate, (*y* - *t<sub>y</sub>*) / *k*. | ||
<a href="#transform_rescaleX" name="transform_rescaleX">#</a> <i>transform</i>.<b>rescaleX</b>(<i>x</i>) | ||
<a href="#transform_rescaleX" name="transform_rescaleX">#</a> <i>transform</i>.<b>rescaleX</b>(<i>x</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L33 "Source") | ||
@@ -278,3 +319,3 @@ Returns a [copy](https://github.com/d3/d3-scale#continuous_copy) of the [continuous scale](https://github.com/d3/d3-scale#continuous-scales) *x* whose [domain](https://github.com/d3/d3-scale#continuous_domain) is transformed. This is implemented by first applying the [inverse *x*-transform](#transform_invertX) on the scale’s [range](https://github.com/d3/d3-scale#continuous_range), and then applying the [inverse scale](https://github.com/d3/d3-scale#continuous_invert) to compute the corresponding domain: | ||
<a href="#transform_rescaleY" name="transform_rescaleY">#</a> <i>transform</i>.<b>rescaleY</b>(<i>y</i>) | ||
<a href="#transform_rescaleY" name="transform_rescaleY">#</a> <i>transform</i>.<b>rescaleY</b>(<i>y</i>) [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L36 "Source") | ||
@@ -293,3 +334,3 @@ Returns a [copy](https://github.com/d3/d3-scale#continuous_copy) of the [continuous scale](https://github.com/d3/d3-scale#continuous-scales) *y* whose [domain](https://github.com/d3/d3-scale#continuous_domain) is transformed. This is implemented by first applying the [inverse *y*-transform](#transform_invertY) on the scale’s [range](https://github.com/d3/d3-scale#continuous_range), and then applying the [inverse scale](https://github.com/d3/d3-scale#continuous_invert) to compute the corresponding domain: | ||
<a href="#transform_toString" name="transform_toString">#</a> <i>transform</i>.<b>toString</b>() | ||
<a href="#transform_toString" name="transform_toString">#</a> <i>transform</i>.<b>toString</b>() [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L39 "Source") | ||
@@ -304,4 +345,4 @@ Returns a string representing the [SVG transform](https://www.w3.org/TR/SVG/coords.html#TransformAttribute) corresponding to this transform. Implemented as: | ||
<a href="#zoomIdentity" name="zoomIdentity">#</a> d3.<b>zoomIdentity</b> | ||
<a href="#zoomIdentity" name="zoomIdentity">#</a> d3.<b>zoomIdentity</b> [<>](https://github.com/d3/d3-zoom/blob/master/src/transform.js#L44 "Source") | ||
The identity transform, where *k* = 1, *t<sub>x</sub>* = *t<sub>y</sub>* = 0. |
@@ -43,2 +43,3 @@ import {dispatch} from "d3-dispatch"; | ||
duration = 250, | ||
interpolate = interpolateZoom, | ||
gestures = [], | ||
@@ -117,5 +118,10 @@ listeners = dispatch("start", "zoom", "end"), | ||
function constrain(transform, extent) { | ||
var dx = Math.min(0, transform.invertX(extent[0][0]) - x0) || Math.max(0, transform.invertX(extent[1][0]) - x1), | ||
dy = Math.min(0, transform.invertY(extent[0][1]) - y0) || Math.max(0, transform.invertY(extent[1][1]) - y1); | ||
return dx || dy ? transform.translate(dx, dy) : transform; | ||
var dx0 = transform.invertX(extent[0][0]) - x0, | ||
dx1 = transform.invertX(extent[1][0]) - x1, | ||
dy0 = transform.invertY(extent[0][1]) - y0, | ||
dy1 = transform.invertY(extent[1][1]) - y1; | ||
return transform.translate( | ||
dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), | ||
dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) | ||
); | ||
} | ||
@@ -140,3 +146,3 @@ | ||
b = typeof transform === "function" ? transform.apply(that, args) : transform, | ||
i = interpolateZoom(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); | ||
i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); | ||
return function(t) { | ||
@@ -284,6 +290,14 @@ if (t === 1) t = b; // Avoid rounding error on end. | ||
} | ||
// If this is a dbltap, reroute to the (optional) dblclick.zoom handler. | ||
if (touchstarting) { | ||
touchstarting = clearTimeout(touchstarting); | ||
if (!g.touch1) return g.end(), dblclicked.apply(this, arguments); | ||
if (!g.touch1) { | ||
g.end(); | ||
p = select(this).on("dblclick.zoom"); | ||
if (p) p.apply(this, arguments); | ||
return; | ||
} | ||
} | ||
if (event.touches.length === n) { | ||
@@ -360,2 +374,6 @@ touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); | ||
zoom.interpolate = function(_) { | ||
return arguments.length ? (interpolate = _, zoom) : interpolate; | ||
}; | ||
zoom.on = function() { | ||
@@ -362,0 +380,0 @@ var value = listeners.on.apply(listeners, arguments); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
260133
802
337