Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active September 3, 2017 11:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mbostock/5348789 to your computer and use it in GitHub Desktop.
Save mbostock/5348789 to your computer and use it in GitHub Desktop.
Concurrent Transitions
license: gpl-3.0

D3 transitions are exclusive and per-element. This typically means that you can’t run multiple transitions concurrently on the same elements; only the last-scheduled transition will run. However, since you can define custom tweens that run arbitrary code during transitions, you can decouple the transition’s element and the transition’s behavior if needed.

In this example, two transitions operate concurrently on the same path element. This works because the two transitions, twizzle and plonk, are created on dummy objects (twizzleLock and plonkLock, respectively) rather than the path element they manipulate.

An alternative approach is to schedule concurrent transitions on parent and child elements.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: black;
stroke: red;
stroke-linejoin: round;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500;
var twizzleLock = {},
plonkLock = {};
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("g")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")")
.append("path")
.attr("d", d3.svg.symbol().type("cross").size(50000))
.call(twizzle, 20000)
.call(plonk, 2000);
function twizzle(path, duration) {
d3.select(twizzleLock).transition()
.duration(duration)
.tween("attr:transform", function() {
var i = d3.interpolateString("rotate(0)", "rotate(720)");
return function(t) { path.attr("transform", i(t)); };
});
setTimeout(function() { twizzle(path, duration); }, (Math.random() + 1) * duration);
}
function plonk(path, duration) {
d3.select(plonkLock).transition()
.duration(duration)
.tween("style:stroke-width", function() {
var i = d3.interpolateString("0px", "30px");
return function(t) { path.style("stroke-width", i(t)); };
})
.transition()
.tween("style:stroke-width", function() {
var i = d3.interpolateString("30px", "0px");
return function(t) { path.style("stroke-width", i(t)); };
});
setTimeout(function() { plonk(path, duration); }, (Math.random() + 2) * duration);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment