block by armollica 9e63b6bb361993436f82c0bb85006330

Curlies

Full Screen

index.html

<!DOCTYPE html>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var numRows = 50,
    numCols = 50,
    numBlobs = numRows * numCols,
    width = 960,
    height = 960,
    blobWidth = Math.max(width / numCols, height / numRows);

var random = d3.randomUniform(-blobWidth / 2, blobWidth / 2);

var canvas = d3.select("body").append("canvas")
  .attr("width", width)
  .attr("height", height);

var context = canvas.node().getContext("2d");

var line = d3.line()
  .x(function(d) { return d[0]; })
  .y(function(d) { return d[1]; })
  .curve(d3.curveCatmullRomClosed.alpha(0.5))
  .context(context);

var blobs = d3.range(numBlobs)
  .map(function(i) {
    var cx = width * Math.floor(i / numRows) / numCols + blobWidth / 2,
        cy = height * (i % numRows) / numRows + blobWidth / 2;
    var blob = createBlob(5);
    return {
      cx: cx,
      cy: cy,
      t: 0,
      dt: (Math.random() - 0.5) * 0.04 + 0.0001,
      blob: blob
    };
  });

var scale = 1,
    deltaScale = 0.01;

var timer = d3.timer(render);

function render() {
  scale += deltaScale;
  if (scale >= 2.5) timer.stop();

  blobs.forEach(function(d) {
    context.save()
    context.translate(d.cx, d.cy);
    context.rotate(d.t += d.dt);
    context.scale(scale, scale);
    context.globalAlpha = 0.01;
    context.beginPath();
    line(d.blob);
    context.strokeStyle = "brown";
    context.stroke();
    context.restore();
  });
}

function createBlob(n) {
  var randomPoints = d3.range(n)
    .map(function(d) { return [random(), random()]; });
  return d3.polygonHull(randomPoints);
}

</script>
</body>
</html>