Skip to content

Instantly share code, notes, and snippets.

@goodforenergy
Created February 8, 2016 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goodforenergy/8f2d7b3236e1964122b5 to your computer and use it in GitHub Desktop.
Save goodforenergy/8f2d7b3236e1964122b5 to your computer and use it in GitHub Desktop.
Animated SVG Path Markers
<?xml version="1.0"?>
<svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<marker id="t" viewBox="0 0 4 4" markerWidth="100%" markerHeight="1" orient="auto" refY="2" refX="0">
<path d="M 0,-1 L 3,2 0,5" class="marker-arrow" />
</marker>
</defs>
</svg>
var SEGMENT_WIDTH = 30,
LINES = [{
volume: 6,
path: 'M50 50 Q 15 200, 50 350'
}, {
volume: 10,
path: 'M100 350 Q 65 200, 100 50'
}, {
volume: 20,
path: 'M150 50 Q 115 200, 150 350'
}, {
volume: 8,
path: 'M200 350 Q 165 200, 200 50'
}],
svg = d3.select('svg');
// Sample the SVG path string 'd' uniformly with the specified precision
function samplePath(d, precision) {
var path,
n,
t,
i,
dt;
path = document.createElementNS(d3.ns.prefix.svg, 'path');
path.setAttribute('d', d);
n = path.getTotalLength();
t = [0];
i = 0;
dt = precision;
while ((i += dt) < n) {
t.push(i);
}
t.push(n);
return t.map(function(t) {
var p = path.getPointAtLength(t),
a = [p.x, p.y];
a.t = t / n;
return a;
});
}
svg.selectAll('.path')
.data(LINES)
.enter()
.append('polyline')
.attr({
points: function(d) {
return samplePath(d.path, SEGMENT_WIDTH)
.reduce(function(prev, curr) {
prev += curr[0] + ',' + curr[1] + ' ';
return prev;
}, '')
},
'stroke-width': function(d) {
return d.volume;
},
class: 'path'
});
var OFFSET = 0;
function flow() {
svg.selectAll('.path')
.attr({
points: function(d) {
return samplePath(d.path, SEGMENT_WIDTH + OFFSET)
.reduce(function(prev, curr) {
prev += curr[0] + ',' + curr[1] + ' ';
return prev;
}, '')
}
});
OFFSET = (OFFSET + 1) % 5;
}
setInterval(flow, 1000);
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
.path {
stroke: lightblue;
fill: transparent;
marker-start: url(#t);
marker-mid: url(#t);
}
.marker-arrow {
stroke: #fff;
stroke-width: 1;
fill: none;
overflow: hidden;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment