Commit ed131d23 authored by Jason Davies's avatar Jason Davies

Add support for interpolating null transform lists.

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
parent b4d79937
......@@ -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);
......@@ -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;
......@@ -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);
......@@ -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) {
......@@ -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());
};
......
This source diff could not be displayed because it is too large. You can view the blob instead.
<!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>
......@@ -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;
......@@ -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);
......
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);
};
......@@ -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};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment