website/scripts/gen-cork.mjs
2026-09-08 19:05:10 -04:00

75 lines
2.0 KiB
JavaScript

import sharp from "sharp";
const W = 56, H = 56;
function mulberry32(a) {
return function () {
a |= 0; a = (a + 0x6D2B79F5) | 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
const rand = mulberry32(20260906);
const shades = [
[0x60, 0x47, 0x2b],
[0x6b, 0x4f, 0x30], [0x6b, 0x4f, 0x30], [0x6b, 0x4f, 0x30],
[0x73, 0x56, 0x36], [0x73, 0x56, 0x36],
[0x7c, 0x5e, 0x3c],
[0x58, 0x40, 0x26],
[0x85, 0x66, 0x43],
];
const grid = new Array(W * H);
const wrap = (v, m) => ((v % m) + m) % m;
const idx = (x, y) => wrap(y, H) * W + wrap(x, W);
for (let i = 0; i < W * H; i++) grid[i] = shades[Math.floor(rand() * shades.length)];
for (let pass = 0; pass < 3; pass++) {
const next = grid.slice();
for (let y = 0; y < H; y++)
for (let x = 0; x < W; x++) {
if (rand() < 0.55) {
const dx = Math.floor(rand() * 3) - 1;
const dy = Math.floor(rand() * 3) - 1;
next[idx(x, y)] = grid[idx(x + dx, y + dy)];
}
}
for (let i = 0; i < W * H; i++) grid[i] = next[i];
}
const dark = [0x40, 0x2e, 0x1b];
const darker = [0x33, 0x24, 0x14];
const light = [0x9c, 0x7c, 0x54];
const lighter = [0xb0, 0x8e, 0x62];
for (let n = 0; n < 150; n++) {
const cx = Math.floor(rand() * W);
const cy = Math.floor(rand() * H);
const bright = rand() < 0.42;
grid[idx(cx, cy)] = bright ? (rand() < 0.5 ? light : lighter) : (rand() < 0.55 ? dark : darker);
if (rand() < 0.28) {
const dx = rand() < 0.5 ? 1 : 0;
const dy = dx ? 0 : 1;
grid[idx(cx + dx, cy + dy)] = bright ? light : dark;
}
}
const buf = Buffer.alloc(W * H * 3);
for (let i = 0; i < W * H; i++) {
buf[i * 3] = grid[i][0];
buf[i * 3 + 1] = grid[i][1];
buf[i * 3 + 2] = grid[i][2];
}
await sharp(buf, { raw: { width: W, height: H, channels: 3 } })
.png({ compressionLevel: 9, palette: true })
.toFile("public/cork.png");
console.log("wrote public/cork.png", W + "x" + H);