Just a little trembling half-bred triangle horse.
forked from veltman's block: Trembling triangle
license: mit |
Just a little trembling half-bred triangle horse.
forked from veltman's block: Trembling triangle
<!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 = 60000, | |
triangle = [[1,249],[63,123],[59,94],[49,109],[42,115],[33,114],[27,106],[26,93],[30,85],[36,68],[34,57],[34,52],[39,42],[40,36],[38,27],[38,13],[46,25],[46,29],[55,26],[59,27],[60,16],[66,18],[70,26],[71,33],[79,37],[89,37],[89,45],[97,45],[94,53],[95,57],[98,55],[125,0],[184,117],[194,115],[206,119],[216,126],[224,137],[227,147],[228,158],[234,167],[243,167],[250,161],[254,155],[255,159],[252,165],[246,170],[249,171],[254,169],[250,175],[255,172],[253,177],[259,173],[257,180],[251,187],[245,187],[234,187],[220,191],[249,248],[182,249],[175,260],[171,271],[170,279],[171,289],[170,293],[162,295],[156,294],[155,290],[165,264],[165,260],[165,249],[148,249],[147,256],[147,262],[152,265],[157,264],[158,275],[154,283],[147,287],[143,287],[140,284],[137,264],[132,257],[136,249],[119,249],[119,255],[124,260],[129,261],[126,264],[127,269],[131,268],[136,269],[138,285],[137,288],[134,291],[131,293],[126,291],[123,288],[120,284],[120,279],[114,283],[109,284],[104,284],[101,282],[99,279],[99,274],[105,266],[111,263],[115,263],[117,262],[110,249],[97,249],[97,256],[98,260],[104,265],[107,264],[97,276],[81,261],[80,249]], | |
line = d3.line().context(context), | |
pixelScale = d3.scaleLinear() | |
.range([2, 8]), | |
depthScale = d3.scaleLinear() | |
.rangeRound([3, 7]), | |
offsetter; | |
context.globalAlpha = 0.1; | |
context.translate(50, 50); | |
d3.timer(function(t){ | |
t = Math.min(t % interval / interval, 1 - t % interval / interval) * 2; | |
offsetter = d3.randomNormal(0, pixelScale(t)); | |
context.clearRect(-50, -50, 960 + 100, 500 + 100); | |
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 = [ | |
a[0] + (b[0] - a[0]) * 0.5 + offsetter(), | |
a[1] + (b[1] - a[1]) * 0.5 + offsetter() | |
]; | |
if (depth === 1) { | |
return [midpoint]; | |
} | |
return [...getBetween(a, midpoint, depth - 1), midpoint, ...getBetween(midpoint, b, depth - 1)]; | |
} | |
</script> |