D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
veltman
Full window
Github gist
Unfolding
Recreating
this GIF
.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <style> body { background-color: #ccc; } path { stroke: black; stroke-width: 3px; stroke-linecap: round; stroke-linejoin: round; fill: #fff; } path:last-of-type { stroke-width: 1px; fill: none; } </style> </head> <body> <svg width="960" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var width = 960, height = 500, sides = d3.scaleLinear().range([1, 12]), svg = d3.select("svg").append("g").attr("transform", "translate(" + width / 2 + ")"), line = d => "M" + d.join("L") + "Z", path = svg.append("path"), inner = svg.append("path"); d3.timer(function(t) { var out = (t = t % 15000 / 15000) < 0.5, progress = sides(d3.easeSinInOut(Math.min(t, 1 - t) * 2)), start = poly(out ? Math.floor(progress) : Math.ceil(progress), out), end = poly(out ? Math.ceil(progress) : Math.floor(progress), !out), remainder = progress % 1; if (!remainder) { end = start; } inner.attr("d", d3.range(3, progress).map(i => line(poly(i))).join(" ")); path.attr("d", line(d3.interpolateArray(start, end)(out ? remainder : 1 - remainder))); }); function poly(s, addPoint) { var r = 120 / (2 * Math.sin(Math.PI / s)), points = s === 1 ? [[0, 0]] : d3 .range(s) .map(i => [ r * Math.cos(2 * Math.PI * i / s - Math.PI / 2 - (s % 2 ? 0 : Math.PI / s)), r * Math.sin(2 * Math.PI * i / s - Math.PI / 2 - (s % 2 ? 0 : Math.PI / s)) ]), bottom = points[s > 2 ? ~~(s / 2) + 1 : 0][1]; points.forEach(d => d[1] += height - bottom - 25); if (addPoint) { if (s % 2) { points.unshift(points[0]); } else { points.splice(1, 0, [0, points[0][1]]); points.push(points.shift()); } } return points; } </script>
https://d3js.org/d3.v4.min.js