Trying to improve the performance of drawing out a bunch of SVG lines by combining them all into a single path element and interpolating one very long stroke-dasharray
pattern.
See also: Dynamic CSS line animation, Canvas line animation
height: 600 |
Trying to improve the performance of drawing out a bunch of SVG lines by combining them all into a single path element and interpolating one very long stroke-dasharray
pattern.
See also: Dynamic CSS line animation, Canvas line animation
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
path { | |
stroke-width: 1px; | |
stroke: #222; | |
fill: none; | |
} | |
</style> | |
<svg width="960" height="600"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/topojson.v2.min.js"></script> | |
<script> | |
var svg = d3.select("svg"), | |
width = 960, | |
height = 600; | |
d3.json("https://d3js.org/us-10m.v1.json", function(err, topo){ | |
var lines = topojson.mesh(topo, topo.objects.states).coordinates; | |
var lengths = svg.selectAll("path") | |
.data(lines) | |
.enter() | |
.append("path") | |
.attr("d", function(d){ | |
return "M" + d.join("L"); | |
}) | |
.nodes() | |
.map(function(node, i){ | |
return { | |
length: node.getTotalLength(), | |
gap: lines[i + 1] ? distanceBetween(lines[i][lines[i].length - 1], lines[i + 1][0]) : 0 | |
}; | |
}); | |
svg.selectAll("path") | |
.remove(); | |
var path = svg.append("path") | |
.attr("d", "M" + d3.merge(lines).join("L")); | |
var start = d3.merge(lengths.map(function(l, i){ | |
return [0, l.length + l.gap]; | |
})); | |
var end = d3.merge(lengths.map(function(l, i){ | |
return [l.length, l.gap]; | |
})); | |
var interpolator = d3.interpolateArray(start, end); | |
timer = d3.timer(function(t){ | |
var progress = 2 * Math.min(t % 5000 / 5000, 1 - t % 5000 / 5000); | |
path.attr("stroke-dasharray", function(d){ | |
return interpolator(progress); | |
}); | |
}); | |
}); | |
function distanceBetween(a, b) { | |
var dx = a[0] - b[0], | |
dy = a[1] - b[1]; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
</script> |