#!/usr/bin/env node /** * Génère le logo/icône du launcher : monogramme "OF" en style voxel (blocs * biseautés façon Minecraft) sur un badge sombre arrondi, accent vert du thème. * * node scripts/gen-logo.mjs -> build/icon.svg * node scripts/gen-logo.mjs --png -> + build/icon.png (1024px) via @resvg/resvg-js * * electron-builder dérive ensuite l'ICO Windows et les PNG Linux depuis * build/icon.png (directories.buildResources = build). */ import { writeFile } from 'node:fs/promises' import { join } from 'node:path' const SIZE = 512 const OUT = join(process.cwd(), 'build') // Palette (cohérente avec src/renderer/src/index.css). const C = { bgTop: '#1b2330', bgBottom: '#0d1014', border: '#2b3444', base: '#3fb950', // vert accent light: '#74e08a', // arête haut/gauche (lumière) dark: '#218a3b' // arête bas/droite (ombre) } // Matrices pixel des lettres (1 = bloc plein). const O = ['01110', '10001', '10001', '10001', '10001', '10001', '01110'] const F = ['1111', '1000', '1000', '1110', '1000', '1000', '1000'] const ROWS = 7 const GAP_COLS = 1 const COLS = O[0].length + GAP_COLS + F[0].length // 5 + 1 + 4 = 10 const cell = 40 // pas de la grille const blockGap = 6 // espace entre blocs (effet grille pixel) const bs = cell - blockGap // taille d'un bloc const bevel = Math.round(bs * 0.18) // épaisseur du biseau const gridW = COLS * cell const gridH = ROWS * cell const x0 = (SIZE - gridW) / 2 const y0 = (SIZE - gridH) / 2 /** Un bloc voxel : base + arêtes claires (haut/gauche) et sombres (bas/droite). */ function block(col, row) { const x = x0 + col * cell + blockGap / 2 const y = y0 + row * cell + blockGap / 2 const t = bevel return [ ``, ``, ``, ``, `` ].join('') } /** Rend une matrice à un décalage de colonnes donné. */ function letter(matrix, colOffset) { const out = [] matrix.forEach((line, r) => { ;[...line].forEach((px, c) => { if (px === '1') out.push(block(colOffset + c, r)) }) }) return out.join('') } const blocks = letter(O, 0) + letter(F, O[0].length + GAP_COLS) const radius = 112 const svg = ` ${blocks} ` async function main() { await writeFile(join(OUT, 'icon.svg'), svg) console.log('✓ build/icon.svg') if (process.argv.includes('--png')) { const { Resvg } = await import('@resvg/resvg-js') const png = new Resvg(svg, { fitTo: { mode: 'width', value: 1024 } }) .render() .asPng() await writeFile(join(OUT, 'icon.png'), png) console.log('✓ build/icon.png (1024px)') } } main().catch((e) => { console.error(e.message) process.exit(1) })