Skip to content

Instantly share code, notes, and snippets.

@veltman
Created April 27, 2017 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save veltman/e8f864c45137b493387a4ebc46ff7da5 to your computer and use it in GitHub Desktop.
Save veltman/e8f864c45137b493387a4ebc46ff7da5 to your computer and use it in GitHub Desktop.
Trembling triangle #2
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment