Skip to content

Instantly share code, notes, and snippets.

@veltman
Last active May 25, 2017 01:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veltman/73f1ffbd388f0fad1e559b47a8a4a9ba to your computer and use it in GitHub Desktop.
Save veltman/73f1ffbd388f0fad1e559b47a8a4a9ba to your computer and use it in GitHub Desktop.
Unfolding
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment