Merge remote-tracking branch 'origin/transition-interpolate' into 2.10.0

Conflicts:
	src/core/interpolate.js
This commit is contained in:
Mike Bostock 2012-08-08 17:32:32 -07:00
Родитель 609ab913de 91630afcab
Коммит f06934831d
9 изменённых файлов: 41 добавлений и 201 удалений

78
d3.v2.js поставляемый
Просмотреть файл

@ -860,7 +860,6 @@
}; };
}; };
d3.interpolateTransform = function(a, b) { d3.interpolateTransform = function(a, b) {
if (n = d3_interpolateTransformSimilar(a, b)) return n;
var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale;
if (ta[0] != tb[0] || ta[1] != tb[1]) { if (ta[0] != tb[0] || ta[1] != tb[1]) {
s.push("translate(", null, ",", null, ")"); s.push("translate(", null, ",", null, ")");
@ -912,68 +911,6 @@
return s.join(""); return s.join("");
}; };
}; };
var d3_interpolateTransformTypes = [ "", "", "translate", "scale", "rotate", "skewX", "skewY" ];
var d3_interpolateTransformSimilar = function(a, b) {
var ga = document.createElementNS(d3.ns.prefix.svg, "g"), gb = document.createElementNS(d3.ns.prefix.svg, "g");
return (d3_interpolateTransformSimilar = function(a, b) {
ga.setAttribute("transform", a);
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;
if (m !== n) {
if (!m) b = d3_interpolateTransformIdentity(a); else if (!n) a = d3_interpolateTransformIdentity(b), n = m; else return;
} else if (!m) return;
while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
type = ta.type;
if (type !== tb.type || !type) return;
switch (type) {
case 2:
{
ra = ta.matrix.e + "," + ta.matrix.f;
rb = tb.matrix.e + "," + tb.matrix.f;
break;
}
case 3:
{
ra = ta.matrix.a + "," + ta.matrix.d;
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
case 1:
case 4:
{
if (type === 1 || ta.matrix.e || ta.matrix.f || tb.matrix.e || tb.matrix.f) {
sa.push(new d3_transform(ta.matrix));
sb.push(new d3_transform(tb.matrix));
continue;
}
}
default:
{
ra = ta.angle;
rb = tb.angle;
}
}
sa.push(type = d3_interpolateTransformTypes[type], "(", ra, ")");
sb.push(type, "(", rb, ")");
}
return d3.interpolateString(sa.join(""), sb.join(""));
})(a, b);
};
function d3_interpolateTransformIdentity(a) {
return {
getItem: function(i) {
return {
type: a.getItem(i).type,
angle: 0,
matrix: d3_transformIdentity
};
}
};
}
d3.interpolateRgb = function(a, b) { d3.interpolateRgb = function(a, b) {
a = d3.rgb(a); a = d3.rgb(a);
b = d3.rgb(b); b = d3.rgb(b);
@ -1843,8 +1780,7 @@
function d3_transitionNull(d, i, a) { function d3_transitionNull(d, i, a) {
return a != "" && d3_transitionRemove; return a != "" && d3_transitionRemove;
} }
function d3_transitionTween(name, b) { function d3_transitionTween(interpolate, b) {
var interpolate = d3_interpolateByName(name);
function transitionFunction(d, i, a) { function transitionFunction(d, i, a) {
var v = b.call(this, d, i); var v = b.call(this, d, i);
return v == null ? a != "" && d3_transitionRemove : a != v && interpolate(a, v); return v == null ? a != "" && d3_transitionRemove : a != v && interpolate(a, v);
@ -1913,8 +1849,9 @@
} }
return d3_transition(subgroups, this.id, this.time).ease(this.ease()); return d3_transition(subgroups, this.id, this.time).ease(this.ease());
}; };
d3_transitionPrototype.attr = function(name, value) { d3_transitionPrototype.attr = function(name, value, interpolate) {
return this.attrTween(name, d3_transitionTween(name, value)); if (arguments.length < 3) interpolate = d3_interpolateByName(name);
return this.attrTween(name, d3_transitionTween(interpolate, value));
}; };
d3_transitionPrototype.attrTween = function(nameNS, tween) { d3_transitionPrototype.attrTween = function(nameNS, tween) {
var name = d3.ns.qualify(nameNS); var name = d3.ns.qualify(nameNS);
@ -1932,9 +1869,10 @@
} }
return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween);
}; };
d3_transitionPrototype.style = function(name, value, priority) { d3_transitionPrototype.style = function(name, value, priority, interpolate) {
if (arguments.length < 3) priority = ""; var n = arguments.length;
return this.styleTween(name, d3_transitionTween(name, value), priority); if (n < 3) interpolate = d3_interpolateByName(name), priority = ""; else if (typeof priority === "function") interpolate = priority, priority = ""; else interpolate = d3_interpolateByName(name);
return this.styleTween(name, d3_transitionTween(interpolate, value), priority);
}; };
d3_transitionPrototype.styleTween = function(name, tween, priority) { d3_transitionPrototype.styleTween = function(name, tween, priority) {
if (arguments.length < 3) priority = ""; if (arguments.length < 3) priority = "";

8
d3.v2.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -2,13 +2,15 @@
<body> <body>
<script src="../../d3.v2.js"></script> <script src="../../d3.v2.js"></script>
<script> <script>
var svg = d3.select("body").append("svg") var svg = d3.select("body").append("svg")
.attr("width", 960) .attr("width", 960)
.attr("height", 500); .attr("height", 500);
var g = svg.append("g") var g = svg.append("g")
.attr("transform", "translate(100,100)") .attr("transform", "translate(100,100)")
.append("g"); .append("g")
.attr("transform", "matrix(1 0 0 1 0 0)rotate(0)");
var rect = g.append("rect") var rect = g.append("rect")
.attr("x", -25) .attr("x", -25)
@ -18,5 +20,6 @@ var rect = g.append("rect")
g.transition() g.transition()
.duration(3000) .duration(3000)
.attr("transform", "matrix(1 0 0 1 100 100)rotate(360)"); .attr("transform", "matrix(1 0 0 1 100 100)rotate(360)", d3.interpolateString);
</script> </script>

Просмотреть файл

@ -2,13 +2,15 @@
<body> <body>
<script src="../../d3.v2.js"></script> <script src="../../d3.v2.js"></script>
<script> <script>
var svg = d3.select("body").append("svg") var svg = d3.select("body").append("svg")
.attr("width", 960) .attr("width", 960)
.attr("height", 500); .attr("height", 500);
var g = svg.append("g") var g = svg.append("g")
.attr("transform", "translate(100,100)") .attr("transform", "translate(100,100)")
.append("g"); .append("g")
.attr("transform", "translate(0,0)rotate(0)");
var rect = g.append("rect") var rect = g.append("rect")
.attr("x", -25) .attr("x", -25)
@ -18,5 +20,6 @@ var rect = g.append("rect")
g.transition() g.transition()
.duration(3000) .duration(3000)
.attr("transform", "translate(100,100)rotate(360)"); .attr("transform", "translate(100,100)rotate(360)", d3.interpolateString);
</script> </script>

Просмотреть файл

@ -51,14 +51,14 @@ var tests = [
{start: 225, end: 170, expected: [-135.00, -148.75, -162.50, -176.25, 170.00]}, {start: 225, end: 170, expected: [-135.00, -148.75, -162.50, -176.25, 170.00]},
{start: -170, end: -225, expected: [-170.00, 176.25, 162.50, 148.75, 135.00]}, {start: -170, end: -225, expected: [-170.00, 176.25, 162.50, 148.75, 135.00]},
{start: -225, end: -170, expected: [ 135.00, 148.75, 162.50, 176.25, -170.00]}, {start: -225, end: -170, expected: [ 135.00, 148.75, 162.50, 176.25, -170.00]},
{start: -170, end: 170, expected: [-170.00, -85.00, 0.00, 85.00, 170.00]}, {start: -170, end: 170, expected: [-170.00, -175.00, 180.00, 175.00, 170.00]},
{start: -170, end: 0, expected: [-170.00, -127.50, -85.00, -42.50, 0.00]}, {start: -170, end: 0, expected: [-170.00, -127.50, -85.00, -42.50, 0.00]},
{start: 170, end: 0, expected: [ 170.00, 127.50, 85.00, 42.50, 0.00]}, {start: 170, end: 0, expected: [ 170.00, 127.50, 85.00, 42.50, 0.00]},
{start: -180, end: 90, expected: [-180.00, -112.50, -45.00, 22.50, 90.00]}, {start: -180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: 180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]}, {start: 180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: -180, end: -90, expected: [-180.00, -157.50, -135.00, -112.50, -90.00]}, {start: -180, end: -90, expected: [-180.00, -157.50, -135.00, -112.50, -90.00]},
{start: 180, end: -90, expected: [ 180.00, 112.50, 45.00, -22.50, -90.00]}, {start: 180, end: -90, expected: [ 180.00, -157.50, -135.00, -112.50, -90.00]},
{start: 780, end: -90, expected: [ 60.00, -157.50, -15.00, 127.50, -90.00]} {start: 780, end: -90, expected: [ 60.00, 22.50, -15.00, -52.50, -90.00]}
]; ];
var tr = d3.select("tbody").selectAll("tr") var tr = d3.select("tbody").selectAll("tr")
@ -118,7 +118,11 @@ gb.append("circle")
function animateExpected(d) { function animateExpected(d) {
d3.select(this).transition() d3.select(this).transition()
.duration(2500) .duration(2500)
.attrTween("transform", function(d) { return d3.interpolateString("rotate(" + d.start + ")", "rotate(" + d.end + ")"); }) .attrTween("transform", function(d) {
var a = d.start % 360, b = d.end % 360;
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
return d3.interpolateString("rotate(" + a + ")", "rotate(" + b + ")");
})
.each("end", animateExpected); .each("end", animateExpected);
} }

Просмотреть файл

@ -93,8 +93,6 @@ d3.interpolateString = function(a, b) {
}; };
d3.interpolateTransform = function(a, b) { d3.interpolateTransform = function(a, b) {
if ((n = d3_interpolateTransformSimilar(a, b))) return n;
var s = [], // string constants and placeholders var s = [], // string constants and placeholders
q = [], // number interpolators q = [], // number interpolators
n, n,
@ -146,115 +144,6 @@ d3.interpolateTransform = function(a, b) {
}; };
}; };
var d3_interpolateTransformTypes = [
"",
"",
"translate",
"scale",
"rotate",
"skewX",
"skewY"
];
// If both the from and to transforms have the same number of transform
// functions and corresponding functions in each transform list are of the same
// type, each transform function is animated with its corresponding destination
// function in isolation using the rules described above. The individual values
// are then applied as a list to produce resulting transform value.
var d3_interpolateTransformSimilar = function(a, b) {
var ga = document.createElementNS(d3.ns.prefix.svg, "g"),
gb = document.createElementNS(d3.ns.prefix.svg, "g");
return (d3_interpolateTransformSimilar = function(a, b) {
ga.setAttribute("transform", a);
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;
// If one of the from or to transforms is "none", the none is replaced
// by an equivalent identity function list for the corresponding transform
// function list. Otherwise, if the transform function lists do not have the
// same number of items, the transforms are each converted into the
// equivalent matrix value and animation proceeds using the rule for a
// single function above.
if (m !== n) {
if (!m) b = d3_interpolateTransformIdentity(a);
else if (!n) a = d3_interpolateTransformIdentity(b), n = m;
else return;
}
// If both the from and to transforms are "none", there is no
// interpolation necessary.
else if (!m) return;
while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
type = ta.type;
// If the transform functions are not the same type, or the type is
// unknown, fallback to the decomposed transform transition.
if (type !== tb.type || !type) return; // unknown
switch (type) {
// For translate, scale and skew functions the individual components of
// the function are interpolated numerically.
case 2: { // translate
ra = ta.matrix.e + "," + ta.matrix.f;
rb = tb.matrix.e + "," + tb.matrix.f;
break;
}
case 3: { // scale
ra = ta.matrix.a + "," + ta.matrix.d;
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
// For matrix and rotations with a non-zero origin, the matrix is
// decomposed using the method described by unmatrix into separate
// translation, scale, rotation and skew matrices, then each decomposed
// transform function is interpolated numerically.
case 1: // matrix
case 4: { // rotate
if (type === 1 || ta.matrix.e || ta.matrix.f || tb.matrix.e || tb.matrix.f) {
sa.push(new d3_transform(ta.matrix));
sb.push(new d3_transform(tb.matrix));
continue;
}
}
default: { // rotate with zero origin, skew
ra = ta.angle;
rb = tb.angle;
}
}
sa.push(type = d3_interpolateTransformTypes[type], "(", ra, ")");
sb.push(type, "(", rb, ")");
}
return d3.interpolateString(sa.join(""), sb.join(""));
})(a, b);
};
function d3_interpolateTransformIdentity(a) {
return {
getItem: function(i) {
return {
type: a.getItem(i).type,
angle: 0,
matrix: d3_transformIdentity
};
}
};
}
d3.interpolateRgb = function(a, b) { d3.interpolateRgb = function(a, b) {
a = d3.rgb(a); a = d3.rgb(a);
b = d3.rgb(b); b = d3.rgb(b);

Просмотреть файл

@ -1,5 +1,6 @@
d3_transitionPrototype.attr = function(name, value) { d3_transitionPrototype.attr = function(name, value, interpolate) {
return this.attrTween(name, d3_transitionTween(name, value)); if (arguments.length < 3) interpolate = d3_interpolateByName(name);
return this.attrTween(name, d3_transitionTween(interpolate, value));
}; };
d3_transitionPrototype.attrTween = function(nameNS, tween) { d3_transitionPrototype.attrTween = function(nameNS, tween) {

Просмотреть файл

@ -1,6 +1,9 @@
d3_transitionPrototype.style = function(name, value, priority) { d3_transitionPrototype.style = function(name, value, priority, interpolate) {
if (arguments.length < 3) priority = ""; var n = arguments.length;
return this.styleTween(name, d3_transitionTween(name, value), priority); if (n < 3) interpolate = d3_interpolateByName(name), priority = "";
else if (typeof priority === "function") interpolate = priority, priority = "";
else interpolate = d3_interpolateByName(name);
return this.styleTween(name, d3_transitionTween(interpolate, value), priority);
}; };
d3_transitionPrototype.styleTween = function(name, tween, priority) { d3_transitionPrototype.styleTween = function(name, tween, priority) {

Просмотреть файл

@ -91,8 +91,7 @@ function d3_transitionNull(d, i, a) {
return a != "" && d3_transitionRemove; return a != "" && d3_transitionRemove;
} }
function d3_transitionTween(name, b) { function d3_transitionTween(interpolate, b) {
var interpolate = d3_interpolateByName(name);
function transitionFunction(d, i, a) { function transitionFunction(d, i, a) {
var v = b.call(this, d, i); var v = b.call(this, d, i);