diff --git a/build/icon.png b/build/icon.png new file mode 100644 index 0000000..cbf1ea5 Binary files /dev/null and b/build/icon.png differ diff --git a/build/icon.svg b/build/icon.svg new file mode 100644 index 0000000..6fc8876 --- /dev/null +++ b/build/icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/scripts/gen-logo.mjs b/scripts/gen-logo.mjs new file mode 100644 index 0000000..6e12363 --- /dev/null +++ b/scripts/gen-logo.mjs @@ -0,0 +1,105 @@ +#!/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) +})