Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from jasondavies/README.md
Last active February 9, 2016 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbostock/3173784 to your computer and use it in GitHub Desktop.
Save mbostock/3173784 to your computer and use it in GitHub Desktop.
Transform Interpolation
license: gpl-3.0

Transitions between transforms are inherently ambiguous; there are multiple valid paths between transforms. For example, when transitioning from “rotate(180)translate(0,-100)” to “rotate(360)translate(0,-100)”, the simplest interpretation rotates from 180º to 360º, but another valid interpretation goes from “translate(0,100)rotate(180)” to “translate(0,-100)rotate(0)”.

d3.interpolateTransform chooses the latter interpretation because it first decomposes transforms into a canonical representation. This allows transitions between more complicated transforms that do not share the same structure.

In D3 2.10, you can change this behavior by specifying an interpolator via d3.tween. For example, you can use d3.interpolateString to interpolation the rotation angle.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
circle {
fill: none;
stroke: #000;
stroke-width: 1.5px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 480,
height = 500;
var svg = d3.select("body").selectAll("svg")
.data(["interpolateTransform", "interpolateString"])
.enter().append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(240,250)");
svg.append("circle")
.attr("r", 100);
svg.append("text")
.attr("dy", "-.3em")
.attr("text-anchor", "middle")
.text(String)
.each(cycle);
function cycle(d) {
d3.select(this).transition()
.duration(4000)
.attrTween("transform", function(interpolate) {
return d3[interpolate](
"rotate(180)translate(0,-100)",
"rotate(360)translate(0,-100)"
);
})
.each("end", cycle);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment