Skip to content

Instantly share code, notes, and snippets.

Forked from jasondavies/
Last active February 9, 2016 01:28
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
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">
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
circle {
fill: none;
stroke: #000;
stroke-width: 1.5px;
<script src="//"></script>
var width = 480,
height = 500;
var svg ="body").selectAll("svg")
.data(["interpolateTransform", "interpolateString"])
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(240,250)");
.attr("r", 100);
.attr("dy", "-.3em")
.attr("text-anchor", "middle")
function cycle(d) {
.attrTween("transform", function(interpolate) {
return d3[interpolate](
.each("end", cycle);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment