Skip to content

Commit

Permalink
Add support for interpolating null transform lists.
Browse files Browse the repository at this point in the history
For consistency with CSS3 [1], a null "from" or "to" transform list is
replaced by an identity function list whose types match those of the
non-null transform list.

[1]: http://www.w3.org/TR/css3-transforms/#animation
  • Loading branch information
jasondavies committed Jul 31, 2012
1 parent b4d7993 commit ed131d2
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 37 deletions.
44 changes: 25 additions & 19 deletions d3.v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,10 @@
gb.setAttribute("transform", b);
a = ga.transform.baseVal;
b = gb.transform.baseVal;
var sa = [], sb = [], i = -1, n = a.numberOfItems, ta, tb, type;
if (n !== b.numberOfItems) return;
var sa = [], sb = [], i = -1, n = a.numberOfItems, m = b.numberOfItems, ta, tb, type;
if (m !== n) {
if (!m) b = d3_interpolateTransformListIdentity(a); else if (!n) a = d3_interpolateTransformListIdentity(b), n = m; else return;
} else if (!m) return;
while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
Expand All @@ -891,13 +893,6 @@
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
case 4:
{
ra = ta.angle % 360;
rb = tb.angle % 360;
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360;
break;
}
default:
{
ra = ta.angle;
Expand All @@ -911,6 +906,17 @@
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
};
}
};
}
d3.interpolateRgb = function(a, b) {
a = d3.rgb(a);
b = d3.rgb(b);
Expand Down Expand Up @@ -1998,18 +2004,11 @@
setTimeout(callback, 17);
};
d3.transform = function(string) {
var g = document.createElementNS(d3.ns.prefix.svg, "g"), identity = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0
};
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 : identity);
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};
function d3_transform(m) {
Expand Down Expand Up @@ -2044,7 +2043,14 @@
a[1] += k * b[1];
return a;
}
var d3_transformDegrees = 180 / Math.PI;
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.

22 changes: 22 additions & 0 deletions examples/transform/null.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<body>
<script src="../../d3.v2.js"></script>
<script>
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);

var g = svg.append("g")
.attr("transform", "translate(100,100)")
.append("g");

var rect = g.append("rect")
.attr("x", -25)
.attr("y", -50)
.attr("width", 50)
.attr("height", 100);

g.transition()
.duration(3000)
.attr("transform", "translate(100,100)rotate(360)");
</script>
29 changes: 19 additions & 10 deletions src/core/interpolate.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,34 +169,37 @@ var d3_interpolateTransformSimilar = function(a, b) {
sb = [],
i = -1,
n = a.numberOfItems,
m = b.numberOfItems,
ta,
tb,
type;

if (n !== b.numberOfItems) return;
if (m !== n) {
if (!m) b = d3_interpolateTransformListIdentity(a);
else if (!n) a = d3_interpolateTransformListIdentity(b), n = m;
else return;
} else if (!m) return;

while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
// SVGTransform.SVG_TRANSFORM_UNKNOWN
// TODO SVGTransform.SVG_TRANSFORM_MATRIX
if ((type = ta.type) !== tb.type || type <= 1) return;
switch (type) {
case 2: {
case 2: { // SVGTransform.SVG_TRANSFORM_TRANSLATE
ra = ta.matrix.e + "," + ta.matrix.f;
rb = tb.matrix.e + "," + tb.matrix.f;
break;
}
case 3: {
case 3: { // SVGTransform.SVG_TRANSFORM_SCALE
ra = ta.matrix.a + "," + ta.matrix.d;
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
case 4: {
ra = ta.angle % 360;
rb = tb.angle % 360;
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path
break;
}
default: {
default: { // SVGTransform.SVG_TRANSFORM_ROTATE
// SVGTransform.SVG_TRANSFORM_SKEWX
// SVGTransform.SVG_TRANSFORM_SKEWY
ra = ta.angle;
rb = tb.angle;
break;
Expand All @@ -210,6 +213,12 @@ var d3_interpolateTransformSimilar = function(a, b) {
})(a, b);
};

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

d3.interpolateRgb = function(a, b) {
a = d3.rgb(a);
b = d3.rgb(b);
Expand Down
8 changes: 4 additions & 4 deletions src/core/transform.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
d3.transform = function(string) {
var g = document.createElementNS(d3.ns.prefix.svg, "g"),
identity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0};
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 : identity);
return new d3_transform(t ? t.matrix : d3_transformIdentity);
})(string);
};

Expand Down Expand Up @@ -57,4 +56,5 @@ function d3_transformCombine(a, b, k) {
return a;
}

var d3_transformDegrees = 180 / Math.PI;
var d3_transformDegrees = 180 / Math.PI,
d3_transformIdentity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0};

0 comments on commit ed131d2

Please sign in to comment.