You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am using this lib for a web page that is drawing SVGs that can have flipped x or y coordinates (the g transform attr is set to scale(1, -1) for example).
I was able to in a not terrible way, add support for this in a local copy of the non minified code - the diff is below. Basically, k represents scale always, but a kxy param maps k to the scaling in x and y. The change means that any new Transform has to carry the kxy param, and the toString() function needs to take kxy into account, the rest basically just works. I wanted to share but am not sure what is needed to make this into a mergeable change - does this look like something that can be mergeable one day?
diff --git a/d3-zoom.v1.js b/d3-zoom.v1.js
index eb97b7d..6128cba 100644
--- a/d3-zoom.v1.js
+++ b/d3-zoom.v1.js
@@ -17,19 +17,21 @@ function ZoomEvent(target, type, transform) {
this.transform = transform;
}
-function Transform(k, x, y) {
+function Transform(k, x, y, kxy) {
this.k = k;
this.x = x;
this.y = y;
+ //This can be undfined, it's handled later
+ this.kxy = kxy;
}
Transform.prototype = {
constructor: Transform,
scale: function(k) {
- return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
+ return k === 1 ? this : new Transform(this.k * k, this.x, this.y, this.kxy);
},
translate: function(x, y) {
- return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
+ return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y, this.kxy);
},
apply: function(point) {
return [point[0] * this.k + this.x, point[1] * this.k + this.y];
@@ -56,12 +58,51 @@ Transform.prototype = {
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 + ")";
+ var scale = "scale(";
+ if (this.kxy) {
+ //TODO: Matrix?
+ scale += this.kxy[0]*this.k+","+this.kxy[1]*this.k;
+ } else {
+ scale += this.k;
+ }
+ scale += ")";
+ return "translate(" + this.x + "," + this.y + ") " + scale;
}
};
var identity = new Transform(1, 0, 0);
+var parse = function(a){
+ //https://stackoverflow.com/a/17838403/557406
+ var b = {};
+ for (var i in a = a.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*,?)+\))+/g)){
+ var c = a[i].match(/[\w\.\-]+/g);
+ b[c.shift()] = c.map(parseFloat);
+ }
+ return b;
+}
+
+var parseTransform = function (transformString){
+ if (!transformString) {
+ return identity;
+ }
+ var params = parse(transformString);
+ if (!params.translate) {
+ params.translate = [0,0];
+ }
+ if (!params.scale) {
+ params.scale = [1];
+ }
+ var k = Math.abs(params.scale[0]);
+ //NOTE: Parse will not have attr empty strings, instead it's just undefined
+ //We only use a pure k if scale is not flipped in x or y
+ if (k === params.scale[0] && (params.scale.length <2 || params.scale[1] === k)){
+ return new Transform(k, params.translate[0], params.translate[1]);
+ }
+ var kxy = [params.scale[0] / k, params.scale[1] / k];
+ return new Transform(k, params.translate[0], params.translate[1], kxy);
+}
+
transform.prototype = Transform.prototype;
function transform(node) {
@@ -136,9 +177,9 @@ var zoom = function() {
wheelDelay = 150,
clickDistance2 = 0;
- function zoom(selection) {
+ function zoom(selection, parsedTransform) {
selection
- .property("__zoom", defaultTransform)
+ .property("__zoom", parsedTransform || defaultTransform)
.on("wheel.zoom", wheeled)
.on("mousedown.zoom", mousedowned)
.on("dblclick.zoom", dblclicked)
@@ -207,12 +248,12 @@ var zoom = function() {
function scale(transform$$1, k) {
k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
- return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);
+ return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y, transform$$1.kxy);
}
function translate(transform$$1, p0, p1) {
var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;
- return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);
+ return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y, transform$$1.kxy);
}
function centroid(extent) {
@@ -235,7 +276,7 @@ var zoom = function() {
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); }
+ else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k, a.kxy); }
g.zoom(null, t);
};
});
@@ -283,15 +324,17 @@ var zoom = function() {
return this;
},
emit: function(type) {
+ //TODO: Fix array if both elements are the same
d3Selection.customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
}
};
function wheeled() {
if (!filter.apply(this, arguments)) return;
+ //Make scale an array for everything here
var g = gesture(this, arguments),
t = this.__zoom,
- k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
+ k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
p = d3Selection.mouse(this);
// If the mouse is in the same location as before, reuse it.
@@ -303,7 +346,7 @@ var zoom = function() {
clearTimeout(g.wheel);
}
- // If this wheel event won’t trigger a transform change, ignore it.
+ // If this wheel event won't trigger a transform change, ignore it.
else if (t.k === k) return;
// Otherwise, capture the mouse point and location at the start.
@@ -496,6 +539,7 @@ var zoom = function() {
exports.zoom = zoom;
exports.zoomTransform = transform;
exports.zoomIdentity = identity;
+exports.parseTransform = parseTransform;
Object.defineProperty(exports, '__esModule', { value: true });
The text was updated successfully, but these errors were encountered:
I am using this lib for a web page that is drawing SVGs that can have flipped x or y coordinates (the g transform attr is set to
scale(1, -1)
for example).I was able to in a not terrible way, add support for this in a local copy of the non minified code - the diff is below. Basically, k represents scale always, but a kxy param maps k to the scaling in x and y. The change means that any new Transform has to carry the kxy param, and the
toString()
function needs to take kxy into account, the rest basically just works. I wanted to share but am not sure what is needed to make this into a mergeable change - does this look like something that can be mergeable one day?The text was updated successfully, but these errors were encountered: