spb/chat-spboucher-ai
Public
1import { PNG } from "pngjs"; import fs from "node:fs";2function icon(size: number, out: string, pad = 0.12) {3 const png = new PNG({ width: size, height: size });4 const r = size * 0.24; const x0 = size * pad, x1 = size * (1 - pad);5 for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {6 const i = (size * y + x) * 4;7 // rounded square dark background8 const inX = x >= x0 && x <= x1, inY = y >= x0 && y <= x1;9 let inside = inX && inY;10 if (inside) { const cx = Math.max(x0 + r, Math.min(x1 - r, x)), cy = Math.max(x0 + r, Math.min(x1 - r, y)); inside = (x - cx) ** 2 + (y - cy) ** 2 <= r * r; }11 if (!inside) { png.data[i + 3] = pad === 0 ? 255 : 0; png.data[i] = 10; png.data[i + 1] = 12; png.data[i + 2] = 16; continue; }12 const t = (x + y) / (2 * size); // gradient blue → amber13 png.data[i] = Math.round(0x6d + (0xf0 - 0x6d) * t * 0.35); png.data[i + 1] = Math.round(0x9c + (0xb3 - 0x9c) * t * 0.35); png.data[i + 2] = Math.round(0xff + (0x5b - 0xff) * t * 0.35); png.data[i + 3] = 255;14 // dark inner card15 const m = size * 0.2; if (x > m && x < size - m && y > m && y < size - m) { png.data[i] = 14; png.data[i + 1] = 17; png.data[i + 2] = 24; }16 // two dots17 for (const [dx, dy, cr, cg, cb] of [[0.34, 0.64, 0x6d, 0x9c, 0xff], [0.66, 0.36, 0xf0, 0xb3, 0x5b]] as const) if ((x - dx * size) ** 2 + (y - dy * size) ** 2 <= (size * 0.07) ** 2) { png.data[i] = cr; png.data[i + 1] = cg; png.data[i + 2] = cb; }18 // curve approx: thick line between dots19 const ax = 0.34 * size, ay = 0.64 * size, bx = 0.66 * size, by = 0.36 * size; const len2 = (bx - ax) ** 2 + (by - ay) ** 2; const tt = Math.max(0, Math.min(1, ((x - ax) * (bx - ax) + (y - ay) * (by - ay)) / len2)); const px = ax + tt * (bx - ax), py = ay + tt * (by - ay);20 if ((x - px) ** 2 + (y - py) ** 2 <= (size * 0.035) ** 2 && tt > 0.15 && tt < 0.85) { png.data[i] = 0x9f; png.data[i + 1] = 0xa8; png.data[i + 2] = 0xc8; }21 }22 fs.writeFileSync(out, PNG.sync.write(png));23}24icon(192, "public/icons/icon-192.png"); icon(512, "public/icons/icon-512.png"); icon(512, "public/icons/maskable-512.png", 0); icon(180, "public/icons/apple-touch-icon.png", 0);25console.log("icons ok");26