| 123456789101112131415161718192021222324252627282930313233343536373839404142 |
- import sharp from 'sharp';
- import { mkdir, readFile, writeFile } from 'node:fs/promises';
- import { join } from 'node:path';
- const svgPath = 'src/lib/assets/favicon.svg';
- const outDir = 'static';
- const svg = await readFile(svgPath);
- await mkdir(outDir, { recursive: true });
- await writeFile(join(outDir, 'favicon.svg'), svg);
- const sizes = [16, 32, 48, 72, 96, 128, 144, 152, 180, 192, 256, 384, 512];
- for (const size of sizes) {
- await sharp(svg).resize(size, size).png().toFile(join(outDir, `icon-${size}x${size}.png`));
- }
- await sharp(svg).resize(180, 180).png().toFile(join(outDir, 'apple-touch-icon.png'));
- await sharp(svg).resize(32, 32).png().toFile(join(outDir, 'favicon.png'));
- await sharp(svg).resize(150, 150).png().toFile(join(outDir, 'mstile-150x150.png'));
- async function maskable(size, name) {
- const pad = Math.round(size * 0.1);
- const inner = size - pad * 2;
- const icon = await sharp(svg).resize(inner, inner).png().toBuffer();
- await sharp({
- create: {
- width: size,
- height: size,
- channels: 4,
- background: { r: 18, g: 18, b: 18, alpha: 1 }
- }
- })
- .composite([{ input: icon, left: pad, top: pad }])
- .png()
- .toFile(join(outDir, name));
- }
- await maskable(192, 'maskable-icon-192x192.png');
- await maskable(512, 'maskable-icon-512x512.png');
- console.log('PWA icons written to static/');
- console.log('Note: favicon.ico is not regenerated here; keep the existing multi-size .ico.');
|