Skip to content

Commit

Permalink
More efficient handling of null transforms.
Browse files Browse the repository at this point in the history
Avoid unnecessary object creation.
  • Loading branch information
jasondavies committed Jul 31, 2012
1 parent ed131d2 commit e9abea5
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 88 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ d3.core.js: \
src/core/formatPrefix.js \
src/core/ease.js \
src/core/event.js \
src/core/transform.js \
src/core/interpolate.js \
src/core/uninterpolate.js \
src/core/rgb.js \
Expand Down Expand Up @@ -118,7 +119,6 @@ d3.core.js: \
src/core/transition-each.js \
src/core/transition-transition.js \
src/core/timer.js \
src/core/transform.js \
src/core/mouse.js \
src/core/touches.js \
src/core/noop.js
Expand Down
127 changes: 63 additions & 64 deletions d3.v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,54 @@
};
return dispatch;
}
d3.transform = function(string) {
var g = document.createElementNS(d3.ns.prefix.svg, "g");
return (d3.transform = function(string) {
g.setAttribute("transform", string);
var t = g.transform.baseVal.consolidate();
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
if (r0[0] * r1[1] < r1[0] * r0[1]) {
r0[0] *= -1;
r0[1] *= -1;
kx *= -1;
kz *= -1;
}
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
this.translate = [ m.e, m.f ];
this.scale = [ kx, ky ];
this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
}
d3_transform.prototype.toString = function() {
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
};
function d3_transformDot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
function d3_transformNormalize(a) {
var k = Math.sqrt(d3_transformDot(a, a));
if (k) {
a[0] /= k;
a[1] /= k;
}
return k;
}
function d3_transformCombine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
}
var d3_transformDegrees = 180 / Math.PI, d3_transformIdentity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
d3.interpolate = function(a, b) {
var i = d3.interpolators.length, f;
while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ;
Expand Down Expand Up @@ -872,14 +920,19 @@
gb.setAttribute("transform", b);
a = ga.transform.baseVal;
b = gb.transform.baseVal;
var sa = [], sb = [], i = -1, n = a.numberOfItems, m = b.numberOfItems, ta, tb, type;
var sa = [], sb = [], i = -1, n = a.numberOfItems, m = b.numberOfItems, ta, tb, type, swap = false;
if (m !== n) {
if (!m) b = d3_interpolateTransformListIdentity(a); else if (!n) a = d3_interpolateTransformListIdentity(b), n = m; else return;
if (!m) tb = d3_interpolateTransformIdentity; else if (!n) {
tb = d3_interpolateTransformIdentity;
n = m, m = 0;
swap = a, a = b, b = swap;
} else return;
} else if (!m) return;
while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
if ((type = ta.type) !== tb.type || type <= 1) return;
type = ta.type;
if (m) tb = b.getItem(i); else tb.type = type;
if (type !== tb.type || type <= 1) return;
switch (type) {
case 2:
{
Expand All @@ -897,26 +950,20 @@
{
ra = ta.angle;
rb = tb.angle;
break;
}
}
sa.push(type = d3_interpolateTransformTypes[type], "(", ra, ")");
sb.push(type, "(", rb, ")");
}
if (swap) swap = sa, sa = sb, sb = swap;
return d3.interpolateString(sa.join(""), sb.join(""));
})(a, b);
};
function d3_interpolateTransformListIdentity(d) {
return {
getItem: function(i) {
return {
type: d.getItem(i).type,
matrix: d3_transformIdentity,
angle: 0
};
}
};
}
var d3_interpolateTransformIdentity = {
type: 0,
angle: 0,
matrix: d3_transformIdentity
};
d3.interpolateRgb = function(a, b) {
a = d3.rgb(a);
b = d3.rgb(b);
Expand Down Expand Up @@ -2003,54 +2050,6 @@
var d3_timer_frame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
setTimeout(callback, 17);
};
d3.transform = function(string) {
var g = document.createElementNS(d3.ns.prefix.svg, "g");
return (d3.transform = function(string) {
g.setAttribute("transform", string);
var t = g.transform.baseVal.consolidate();
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
if (r0[0] * r1[1] < r1[0] * r0[1]) {
r0[0] *= -1;
r0[1] *= -1;
kx *= -1;
kz *= -1;
}
this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
this.translate = [ m.e, m.f ];
this.scale = [ kx, ky ];
this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
}
d3_transform.prototype.toString = function() {
return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")";
};
function d3_transformDot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
function d3_transformNormalize(a) {
var k = Math.sqrt(d3_transformDot(a, a));
if (k) {
a[0] /= k;
a[1] /= k;
}
return k;
}
function d3_transformCombine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
}
var d3_transformDegrees = 180 / Math.PI, d3_transformIdentity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
d3.mouse = function(container) {
return d3_mousePoint(container, d3_eventSource());
};
Expand Down
8 changes: 4 additions & 4 deletions d3.v2.min.js

Large diffs are not rendered by default.

45 changes: 26 additions & 19 deletions src/core/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,52 +172,59 @@ var d3_interpolateTransformSimilar = function(a, b) {
m = b.numberOfItems,
ta,
tb,
type;
type,
swap = false;

if (m !== n) {
if (!m) b = d3_interpolateTransformListIdentity(a);
else if (!n) a = d3_interpolateTransformListIdentity(b), n = m;
else return;
if (!m) tb = d3_interpolateTransformIdentity;
else if (!n) {
tb = d3_interpolateTransformIdentity;
n = m, m = 0;
swap = a, a = b, b = swap;
} else return;
} else if (!m) return;

while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
type = ta.type;
if (m) tb = b.getItem(i);
else tb.type = type;
// SVGTransform.SVG_TRANSFORM_UNKNOWN
// TODO SVGTransform.SVG_TRANSFORM_MATRIX
if ((type = ta.type) !== tb.type || type <= 1) return;
if (type !== tb.type || type <= 1) return;
switch (type) {
case 2: { // SVGTransform.SVG_TRANSFORM_TRANSLATE
// TODO SVGTransform.SVG_TRANSFORM_MATRIX
case 2: {
// SVGTransform.SVG_TRANSFORM_TRANSLATE
ra = ta.matrix.e + "," + ta.matrix.f;
rb = tb.matrix.e + "," + tb.matrix.f;
break;
}
case 3: { // SVGTransform.SVG_TRANSFORM_SCALE
case 3: {
// SVGTransform.SVG_TRANSFORM_SCALE
ra = ta.matrix.a + "," + ta.matrix.d;
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
default: { // SVGTransform.SVG_TRANSFORM_ROTATE
// SVGTransform.SVG_TRANSFORM_SKEWX
// SVGTransform.SVG_TRANSFORM_SKEWY
default: {
// SVGTransform.SVG_TRANSFORM_ROTATE
// SVGTransform.SVG_TRANSFORM_SKEWX
// SVGTransform.SVG_TRANSFORM_SKEWY
ra = ta.angle;
rb = tb.angle;
break;
}
}
sa.push(type = d3_interpolateTransformTypes[type], "(", ra, ")");
sb.push(type, "(", rb, ")");
}

if (swap) swap = sa, sa = sb, sb = swap;
return d3.interpolateString(sa.join(""), sb.join(""));
})(a, b);
};

function d3_interpolateTransformListIdentity(d) {
return {getItem: function(i) {
return {type: d.getItem(i).type, matrix: d3_transformIdentity, angle: 0};
}};
}
var d3_interpolateTransformIdentity = {
type: 0, angle: 0,
matrix: d3_transformIdentity
};

d3.interpolateRgb = function(a, b) {
a = d3.rgb(a);
Expand Down

0 comments on commit e9abea5

Please sign in to comment.