79 lines
2.4 KiB
JavaScript
79 lines
2.4 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { PNG } from "pngjs";
|
|
|
|
const root = process.cwd();
|
|
const output = path.join(root, "build", "icon.ico");
|
|
const size = 256;
|
|
const png = new PNG({ width: size, height: size });
|
|
const glyph = [
|
|
"0111000000",
|
|
"1000100000",
|
|
"1000100000",
|
|
"1000100000",
|
|
"1111100000",
|
|
"1000100000",
|
|
"1000100000",
|
|
"1000100000",
|
|
"1000100000",
|
|
"1000100000"
|
|
];
|
|
|
|
function insideRoundedSquare(x, y, radius) {
|
|
const clampX = Math.min(Math.max(x, radius), size - 1 - radius);
|
|
const clampY = Math.min(Math.max(y, radius), size - 1 - radius);
|
|
return (x - clampX) ** 2 + (y - clampY) ** 2 <= radius ** 2;
|
|
}
|
|
|
|
for (let y = 0; y < size; y += 1) {
|
|
for (let x = 0; x < size; x += 1) {
|
|
const index = (size * y + x) << 2;
|
|
const visible = insideRoundedSquare(x, y, 34);
|
|
const gradient = (x + y) / (2 * (size - 1));
|
|
png.data[index] = visible ? Math.round(37 + (30 - 37) * gradient) : 0;
|
|
png.data[index + 1] = visible ? Math.round(99 + (58 - 99) * gradient) : 0;
|
|
png.data[index + 2] = visible ? Math.round(235 + (138 - 235) * gradient) : 0;
|
|
png.data[index + 3] = visible ? 255 : 0;
|
|
|
|
if (visible) {
|
|
const glyphX = Math.round((x - 78) / 10);
|
|
const glyphY = Math.round((y - 68) / 12);
|
|
if (glyphY >= 0 && glyphY < glyph.length && glyphX >= 0 && glyphX < glyph[glyphY].length && glyph[glyphY][glyphX] === "1") {
|
|
png.data[index] = 255;
|
|
png.data[index + 1] = 255;
|
|
png.data[index + 2] = 255;
|
|
png.data[index + 3] = 255;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const chunks = [];
|
|
png.pack()
|
|
.on("data", (chunk) => chunks.push(chunk))
|
|
.on("end", () => {
|
|
const image = Buffer.concat(chunks);
|
|
const directory = Buffer.alloc(6);
|
|
directory.writeUInt16LE(0, 0);
|
|
directory.writeUInt16LE(1, 2);
|
|
directory.writeUInt16LE(1, 4);
|
|
|
|
const entry = Buffer.alloc(16);
|
|
entry[0] = 0;
|
|
entry[1] = 0;
|
|
entry[2] = 0;
|
|
entry[3] = 0;
|
|
entry.writeUInt16LE(1, 4);
|
|
entry.writeUInt16LE(32, 6);
|
|
entry.writeUInt32LE(image.length, 8);
|
|
entry.writeUInt32LE(22, 12);
|
|
|
|
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
fs.writeFileSync(output, Buffer.concat([directory, entry, image]));
|
|
console.log(`[icon] generated ${output} (${image.length + 22} bytes)`);
|
|
})
|
|
.on("error", (error) => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
}); |