kanban-dev-webapp/scripts/build-icons.ts
Dave 75c321bad2 feat(pwa): icon build script and committed PNG outputs
Phase 8b Task 2. @resvg/resvg-js renders public/icons/source.svg
into the four PNG sizes the manifest + iOS expect: 192, 512,
maskable-512 (Android safe-zone), and apple-touch-icon-180.
Build is one-shot — outputs are committed, runtime doesn't ship
the dep.
2026-09-21 11:22:32 +02:00

46 lines
1.6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* One-shot: render public/icons/source.svg into the four PNGs the manifest
* and iOS expect.
*
* Run with `npx tsx scripts/build-icons.ts` from the project root. The
* output is committed so the deployed bundle does not need `@resvg/resvg-js`
* at runtime.
*
* Sizes follow the manifest spec:
* - icon-192.png: 192×192, used by Android Chrome and most launchers
* - icon-512.png: 512×512, used by Android splash and Play Store
* - icon-maskable-512.png: 512×512 with the safe-zone padding Android
* applies when the icon is shown in a non-square mask (e.g. circle,
* squircle). The source SVG already has 96/512 = ~19% corner radius,
* which is within Android's safe zone.
* - apple-touch-icon.png: 180×180, used by iOS Safari's "Add to Home
* Screen". iOS does not honour the manifest for this; the link is in
* the layout's <head>.
*/
import { readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { Resvg } from "@resvg/resvg-js";
const root = join(process.cwd(), "public", "icons");
const svg = readFileSync(join(root, "source.svg"), "utf8");
const targets = [
{ file: "icon-192.png", size: 192 },
{ file: "icon-512.png", size: 512 },
{ file: "icon-maskable-512.png", size: 512 },
{ file: "apple-touch-icon.png", size: 180 },
];
for (const target of targets) {
const png = new Resvg(svg, {
fitTo: { mode: "width", value: target.size },
})
.render()
.asPng();
writeFileSync(join(root, target.file), png);
console.log(` + ${target.file} (${target.size}x${target.size})`);
}
console.log("Done.");