81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from 'fs';
|
|
import zlib from 'zlib';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const dir = path.join(__dirname, '..', 'public', 'icons');
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
|
|
function crc32(data) {
|
|
let crc = 0xffffffff;
|
|
const table = new Int32Array(256);
|
|
for (let i = 0; i < 256; i++) {
|
|
let c = i;
|
|
for (let j = 0; j < 8; j++) c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
|
|
table[i] = c;
|
|
}
|
|
for (let i = 0; i < data.length; i++) crc = table[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);
|
|
return (crc ^ 0xffffffff) >>> 0;
|
|
}
|
|
|
|
function chunk(type, data) {
|
|
const len = Buffer.alloc(4);
|
|
len.writeUInt32BE(data.length);
|
|
const typeData = Buffer.concat([Buffer.from(type), data]);
|
|
const crcBuf = Buffer.alloc(4);
|
|
crcBuf.writeUInt32BE(crc32(typeData));
|
|
return Buffer.concat([len, typeData, crcBuf]);
|
|
}
|
|
|
|
function makePNG(w, h) {
|
|
const rowBytes = 1 + w * 3;
|
|
const buf = Buffer.alloc(rowBytes * h);
|
|
const cx = w / 2, cy = h / 2;
|
|
const outerR = Math.min(w, h) / 2 - 2;
|
|
const innerR = outerR * 0.65;
|
|
|
|
let offset = 0;
|
|
for (let y = 0; y < h; y++) {
|
|
buf[offset++] = 0; // filter none
|
|
for (let x = 0; x < w; x++) {
|
|
const dx = x - cx, dy = y - cy;
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
if (dist <= outerR && dist >= innerR) {
|
|
buf[offset++] = 90; buf[offset++] = 140; buf[offset++] = 255;
|
|
} else {
|
|
buf[offset++] = 6; buf[offset++] = 7; buf[offset++] = 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
const compressed = zlib.deflateSync(buf.slice(0, offset));
|
|
const ihdr = Buffer.alloc(13);
|
|
ihdr.writeUInt32BE(w, 0);
|
|
ihdr.writeUInt32BE(h, 4);
|
|
ihdr[8] = 8; ihdr[9] = 2;
|
|
|
|
return Buffer.concat([
|
|
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
|
|
chunk('IHDR', ihdr),
|
|
chunk('IDAT', compressed),
|
|
chunk('IEND', Buffer.alloc(0))
|
|
]);
|
|
}
|
|
|
|
const icons = [
|
|
[192, 'icon-192.png'],
|
|
[512, 'icon-512.png'],
|
|
[512, 'icon-512-maskable.png'],
|
|
[180, 'apple-touch-icon.png'],
|
|
];
|
|
|
|
for (const [size, name] of icons) {
|
|
const png = makePNG(size, size);
|
|
fs.writeFileSync(path.join(dir, name), png);
|
|
console.log(`Created ${name} (${png.length} bytes)`);
|
|
}
|
|
|
|
console.log('Done!');
|