eratic / scripts / make-icons.mjs
238 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env node
/**
 * Generate the raster icons every site needs.
 *
 *   node scripts/make-icons.mjs
 *
 * Run this when the mark changes, and commit the results. It is deliberately
 * not part of the build: the icon changes roughly never, and rasterising it on
 * every deploy would be work done for nothing.
 *
 * favicon.svg is hand-written and theme-aware (it inverts in dark mode).
 * apple-touch-icon.png cannot be: iOS ignores transparency, applies its own
 * rounding, and has no notion of a colour scheme — so it gets a fixed dark
 * square with the light mark, full bleed.
 */

import { writeFile } from 'node:fs/promises';
import sharp from 'sharp';

const SITES = ['home', 'blog', 'fav', 'io'];
const ROOT = new URL('..', import.meta.url).pathname;

const SURFACE = '#141619';
const INK = '#faf9f7';

// The same mark as favicon.svg, with the media query flattened away and no
// corner radius — iOS rounds it itself, and rounding twice looks wrong.
const mark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="180" height="180">
	<rect width="32" height="32" fill="${SURFACE}"/>
	<path fill="${INK}" d="M16 7.5a8.5 8.5 0 1 0 6.9 13.44l-2.62-1.72A5.4 5.4 0 0 1 10.8 17.5h13.6A8.5 8.5 0 0 0 16 7.5Zm0 3.1a5.4 5.4 0 0 1 5.1 3.6H10.9a5.4 5.4 0 0 1 5.1-3.6Z"/>
</svg>`;

const png = await sharp(Buffer.from(mark)).png({ compressionLevel: 9 }).toBuffer();

for (const site of SITES) {
	const path = `${ROOT}sites/${site}/public/apple-touch-icon.png`;
	await writeFile(path, png);
	console.log(`✓ sites/${site}/public/apple-touch-icon.png  (${(png.length / 1024).toFixed(1)} kB)`);
}

static mirror of HEAD · about · clone: git clone https://git.makefuture.ro/eratic.git