// Renders public/og.png (1200×630), the preview image for link shares: the name, the // waveform from the hero and three editor previews. Run with `npm run og` after the look // changes. The text is set in Roboto Condensed, loaded from the plugins' own font folder. import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; const root = new URL('../', import.meta.url); const repo = new URL('../', root); const W = 1200; const H = 630; // librsvg finds fonts through fontconfig; point it at the embedded editor fonts. const fonts = await mkdtemp(join(tmpdir(), 'og-fonts-')); await writeFile( join(fonts, 'fonts.conf'), ` ${new URL('plugins/common/ui/assets/', repo).pathname}${fonts} `, ); process.env.FONTCONFIG_FILE = join(fonts, 'fonts.conf'); const { default: sharp } = await import('sharp'); // Knurl's Fry pattern on a tanh saw, as in src/components/Hero.astro. const pattern = [0, -14, -5, -14].map((db) => 10 ** (db / 20)); const points = []; for (let i = 0; i <= 700; i++) { const phase = (i / 700) * 6; const cycle = Math.floor(phase); const frac = phase - cycle; let g = pattern[cycle % 4]; if (frac > 0.85) { const t = (frac - 0.85) / 0.15; g += (pattern[(cycle + 1) % 4] - g) * (0.5 - 0.5 * Math.cos(Math.PI * t)); } const y = Math.tanh(2.2 * (2 * frac - 1)) / Math.tanh(2.2); points.push(`${(70 + (i / 700) * 1060).toFixed(1)},${(492 - y * g * 68).toFixed(1)}`); } const background = Buffer.from(` CLAP PLUGINS FOR FL STUDIO BASS FOUNDRY RIDDIM · DUBSTEP · BASS MUSIC — FL.NARL.IO `); const shot = async (name, width) => { const img = sharp(await readFile(new URL(`docs/${name}/assets/editor.png`, repo))).resize(width); const { height } = await img.clone().toBuffer({ resolveWithObject: true }).then((r) => r.info); const mask = Buffer.from(``); return img.composite([{ input: mask, blend: 'dest-in' }]).png().toBuffer(); }; await sharp(background) .composite([ { input: await shot('lathe', 430), left: 700, top: 36 }, { input: await shot('knurl', 430), left: 640, top: 116 }, ]) .png({ compressionLevel: 9 }) .toFile(new URL('public/og.png', root).pathname); await rm(fonts, { recursive: true }); console.log('wrote public/og.png');