Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from scameron/index.html
Last active February 9, 2016 01:27
Show Gist options
  • Save mbostock/3151228 to your computer and use it in GitHub Desktop.
Save mbostock/3151228 to your computer and use it in GitHub Desktop.
Animated textPath
license: gpl-3.0

This example demonstrates how to animate a path and a textPath at the same time. I wouldn’t use this technique—the text is scrunched up at the beginning of the arc at the beginning of the animation. Instead, I would use the arc to clip the text, so that the text is revealed as the arc expands.

This example also demonstrates two unfortunate bugs in WebKit browsers:

  • You can’t select textPath elements because of a bug in how WebKit handles case-sensitive element names. See bug 83438. WebKit shows no sign of fixing this bug, unfortunately.

  • Updating a path element by itself does not trigger redraw on dependent elements that reference this path. So, even though we update the path, the referencing textPath element will not be redrawn. To workaround this update bug, we create a custom transition that repeatedly sets the textPath’s xlink:href attribute to “#path”.

See related Stack Overflow question.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: #3182bd;
}
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 24px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var arc = d3.svg.arc()
.innerRadius(180)
.outerRadius(220)
.startAngle(0)
.endAngle(function(t) { return t * 2 * Math.PI / 3; });
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("transform", "translate(480,250)");
svg.append("path")
.attr("id", "path")
.attr("d", arc(1));
svg.append("text")
.attr("x", 8)
.attr("dy", 28)
.append("textPath")
.attr("class", "textpath")
.attr("xlink:href", "#path")
.text("Hello, curved textPath!");
var transition = svg.transition()
.duration(5000);
transition.selectAll("#path")
.attrTween("d", function() { return arc; });
transition.selectAll(".textpath")
.attrTween("xlink:href", function() { return function() { return "#path"; }; });
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment