block by veltman 73f1ffbd388f0fad1e559b47a8a4a9ba

Unfolding

Full Screen

Recreating this GIF.

index.html

<!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>