Similar to this shaky triangle but with a different offsetting technique.
forked from veltman's block: Trembling triangle #2
license: mit |
Similar to this shaky triangle but with a different offsetting technique.
forked from veltman's block: 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> |
�PNG | |