block by jeremycflin bbd1a5de6b77e6001680235dc8c2b967

Trembling triangle #2

Full Screen

Similar to this shaky triangle but with a different offsetting technique.

forked from veltman‘s block: Trembling triangle #2

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
</head>
<body>
<canvas width="960" height="500"></canvas>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

let context = document.querySelector("canvas").getContext("2d"),
    interval = 45000,
    triangle = [[480, 50], [680, 450], [280, 450]],
    line = d3.line().context(context),
    pixelScale = d3.scaleLinear()
      .range([2, 8]),
    depthScale = d3.scaleLinear()
      .rangeRound([3, 7]),
    getDistance = d3.randomNormal(0.5, 0.15),
    getOffset;

context.globalAlpha = 0.1;

d3.timer(function(t){
  t = Math.min(t % interval / interval, 1 - t % interval / interval) * 2;

  getOffset = d3.randomNormal(0, pixelScale(t));

  context.clearRect(0, 0, 960, 500);
  context.fillStyle = d3.interpolateWarm(t / 2);
  for (let i = 0; i < 10; i++) {
    context.beginPath();
    line(tremble(triangle, depthScale(t)));
    context.closePath();
    context.fill();
  }

});

function tremble(shape, depth) {
  return shape.reduce((newPoints, val, i) => {
    return [...newPoints, val, ...getBetween(val, shape[i + 1] || shape[0], depth)];
  }, []);
}

function getBetween(a, b, depth) {
  const midpoint = getMidpoint(a, b);

  if (depth === 1) {
    return [midpoint];
  }

  return [...getBetween(a, midpoint, depth - 1), midpoint, ...getBetween(midpoint, b, depth - 1)];

}

function getMidpoint(a, b) {
  let along = pointAlong(a, b, getDistance()),
      distance = distanceBetween(a, b),
      offset = getOffset();

  return [
    along[0] + offset * (a[1] - b[1]) / distance,
    along[1] - offset * (a[0] - b[0]) / distance
  ];
}

function distanceBetween(a, b) {
  return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
}

function pointAlong(a, b, pct) {
  return [a[0] + (b[0] - a[0]) * pct, a[1] + (b[1] - a[1]) * pct];
}




</script>