Files
windwiderstand/scripts/generate-pwa-icons.mjs
Peter Meier c12d626507
Deploy / verify (push) Successful in 1m7s
Deploy / deploy (push) Successful in 1m45s
feat(pwa): installierbar + Offline-Grundgeruest
- Manifest (name/standalone/theme-color wald), Icons aus echtem Logo
  (192/512/maskable/apple-touch) via scripts/generate-pwa-icons.mjs
- app.html: manifest + theme-color + apple-touch-icon + iOS-Meta
- service-worker.ts: precache Build-Assets, Seiten network-first mit
  Offline-Cache-Fallback (SvelteKit registriert autom. in Prod)
- Push (VAPID) folgt separat

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:58:35 +02:00

35 lines
1.3 KiB
JavaScript

// Erzeugt PWA-Icons aus dem echten App-Logo (logo_v3.svg) auf hellem Grund.
// Läuft manuell: `node scripts/generate-pwa-icons.mjs`
import sharp from "sharp";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
const staticDir = join(root, "static");
const BG = "#f0f5f1"; // wald-50 (wie Header-Hintergrund)
const logoSvg = readFileSync(
join(root, "..", "cms_content", "windwiderstand", "assets", "logo_v3.svg"),
"utf8",
);
async function makeIcon(size, logoRatio, out) {
const logoPx = Math.round(size * logoRatio);
const logo = await sharp(Buffer.from(logoSvg), { density: 384 })
.resize(logoPx, logoPx, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } })
.png()
.toBuffer();
const pad = Math.round((size - logoPx) / 2);
await sharp({ create: { width: size, height: size, channels: 4, background: BG } })
.composite([{ input: logo, top: pad, left: pad }])
.png()
.toFile(join(staticDir, out));
console.log("wrote", out, `${size}px`);
}
await makeIcon(192, 0.78, "icon-192.png");
await makeIcon(512, 0.78, "icon-512.png");
await makeIcon(512, 0.6, "icon-maskable-512.png"); // mehr Rand für Maskable-Safe-Zone
await makeIcon(180, 0.78, "apple-touch-icon.png");