{
restart;
const w = 1024,
h = 768,
sz = 400;
const n = 2000;
const sep = 10;
const relaxSteps = 2;
const shuffleRate = 100;
let ctx = DOM.context2d(w, h, 1);
const square = [
[0, 0],
[sz, 0],
[sz, sz],
[0, sz]
];
const rand = d3.randomUniform(-1, 1);
const [hmin, hmax, hvar] = [0, 360, 180 * colorVar],
[smin, smax, svar] = [50, 100, 50 * colorVar],
[lmin, lmax, lvar] = [30, 80, 50 * colorVar];
const baseColor = {
h: d3.randomInt(hmin, hmax)(),
s: d3.randomInt(smin, smax)(),
l: d3.randomInt(lmin, lmax)()
};
const varyColor = ({ h, s, l }) => ({
h: Math.min(Math.max(h + rand() * hvar, hmin), hmax),
s: Math.min(Math.max(s + rand() * svar, smin), smax),
l: Math.min(Math.max(l + rand() * lvar, lmin), lmax)
});
let pieces = [{ poly: square, color: baseColor }];
const draw = () => {
ctx.save();
ctx.fillStyle = "black";
ctx.fillRect(0, 0, w, h);
ctx.translate((w - sz) / 2, (h - sz) / 2);
for (let { poly, color } of pieces) {
ctx.fillStyle = `hsl(${color.h},${color.s}%,${color.l}%)`;
ctx.beginPath();
for (let [x, y] of poly) ctx.lineTo(x, y);
ctx.closePath();
ctx.fill();
}
ctx.restore();
};
draw();
yield ctx.canvas;
if (slowStart.length) await Promises.delay(1000);
for (let i = 0; i < n; i++) {
let j = d3.randomInt(0, pieces.length)();
const piece = pieces.shift();
if (i % shuffleRate == 0) pieces = d3.shuffle(pieces);
let { poly, color } = piece;
let a = centroid(poly);
let v = PCA(poly);
v = [-v[1], v[0]];
vec2.rotate(v, v, [0, 0], (rand() * (splitDirVar * Math.PI)) / 2);
let b = vec2.add([], a, v);
let [left, right] = split(poly, a, b);
let [leftColor, rightColor] = [varyColor(color), varyColor(color)];
for (let poly of [left, right]) {
const c = centroid(poly);
const rotAng = rand() * rotVar * Math.PI;
const shiftAng = Math.random() * Math.PI * 2;
const shift = [sep * Math.cos(shiftAng), sep * Math.sin(shiftAng)];
for (let p of poly) {
vec2.rotate(p, p, c, rotAng);
}
}
pieces.push(
{ poly: left, color: leftColor },
{ poly: right, color: rightColor }
);
let polys = pieces.map((p) => p.poly);
for (let j = 0; j < relaxSteps; j++) {
separatePolygons(polys);
pieces.forEach((piece, i) => (piece.poly = polys[i]));
draw();
yield ctx.canvas;
}
if (slowStart.length) await Promises.delay(Math.max(1, 500 - i * 5));
}
}