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> |