This example demonstrates how to use the getTotalLength and getPointAtLength methods on SVG path elements to interpolate a point along a Catmull–Rom spline.
A related technique is stroke dash interpolation.
license: gpl-3.0 |
This example demonstrates how to use the getTotalLength and getPointAtLength methods on SVG path elements to interpolate a point along a Catmull–Rom spline.
A related technique is stroke dash interpolation.
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<body> | |
<style> | |
path { | |
fill: none; | |
stroke: #000; | |
stroke-width: 3px; | |
} | |
circle { | |
fill: steelblue; | |
stroke: #fff; | |
stroke-width: 3px; | |
} | |
</style> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
var points = [ | |
[480, 200], | |
[580, 400], | |
[680, 100], | |
[780, 300], | |
[180, 300], | |
[280, 100], | |
[380, 400] | |
]; | |
var svg = d3.select("body").append("svg") | |
.attr("width", 960) | |
.attr("height", 500); | |
var path = svg.append("path") | |
.data([points]) | |
.attr("d", d3.svg.line() | |
.tension(0) // Catmull–Rom | |
.interpolate("cardinal-closed")); | |
svg.selectAll(".point") | |
.data(points) | |
.enter().append("circle") | |
.attr("r", 4) | |
.attr("transform", function(d) { return "translate(" + d + ")"; }); | |
var circle = svg.append("circle") | |
.attr("r", 13) | |
.attr("transform", "translate(" + points[0] + ")"); | |
transition(); | |
function transition() { | |
circle.transition() | |
.duration(10000) | |
.attrTween("transform", translateAlong(path.node())) | |
.each("end", transition); | |
} | |
// Returns an attrTween for translating along the specified path element. | |
function translateAlong(path) { | |
var l = path.getTotalLength(); | |
return function(d, i, a) { | |
return function(t) { | |
var p = path.getPointAtLength(t * l); | |
return "translate(" + p.x + "," + p.y + ")"; | |
}; | |
}; | |
} | |
</script> |