Skip to content

Instantly share code, notes, and snippets.

@benpickles
Last active November 20, 2016 16:23
Show Gist options
  • Save benpickles/37db7010d9e2cbbf13b0 to your computer and use it in GitHub Desktop.
Save benpickles/37db7010d9e2cbbf13b0 to your computer and use it in GitHub Desktop.
Follow SVG <path>
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.path {
fill: transparent;
stroke: #ddd;
stroke-dasharray: 2 4;
stroke-width: 2;
}
</style>
<svg height="500" width="960">
<path class="path" d="M279,415 C118,274 133,180 227,119 C321,59 445,-0 510,105 C574,212 579,364 507,325 C435,287 513,129 597,120 C681,111 795,103 826,217 C857,332 846,438 787,449" />
<g>
<path d="M0,8 L8,0 L0,-8 L0,-4 L-8,-4 L-8,4 L0,4 Z" />
</g>
</svg>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var svg = d3.select('svg')
, path = svg.select('path.path')
, arrow = svg.select('g')
arrow.attr('transform', moveToPointAtLength(path.node(), 0))
;(function transition(reverse) {
arrow.transition()
.duration(10000)
.attrTween('transform', followPath(path.node(), reverse))
.each('end', function() {
transition(!reverse)
})
})();
function followPath(node, reverse) {
var length = node.getTotalLength()
return function() {
return function(t) {
var l = length * t
if (reverse) l = length - l
return moveToPointAtLength(node, l, reverse)
}
}
}
function moveToPointAtLength(node, l, reverse) {
var l0 = Math.max(0, l - 1)
, l1 = l + 1
, p = node.getPointAtLength(l)
, p0 = node.getPointAtLength(l0)
, p1 = node.getPointAtLength(l1)
, dx = reverse ? p0.x - p1.x : p1.x - p0.x
, dy = reverse ? p0.y - p1.y : p1.y - p0.y
, angle = Math.atan2(dy, dx) * 180 / Math.PI
, translate = 'translate(' + p.x + ',' + p.y + ')'
, rotate = 'rotate(' + angle + ')'
return translate + rotate
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment