/* templates.mjs — render the composition templates (famous-composition skeletons) to SVGs + .mjs configs + a contact sheet + an archive-wall MATRIX. Usage: node tools/templates.mjs [size] [outDir] [seedSalt] seedSalt → appended to each seed for a fresh batch (e.g. set 2). */ import { writeFileSync, mkdirSync } from 'node:fs'; import { TEMPLATES, buildTemplate } from '../src/compose/templates.js'; import { renderComposition } from '../src/compose/composition.js'; const SIZE = +(process.argv[2] || 1300); const OUT = process.argv[3] || 'output/templates'; const SALT = process.argv[4] || ''; mkdirSync(OUT, { recursive: true }); let n = 0; const items = []; for (const t of TEMPLATES) { for (let i = 0; i < t.reps; i++) { const comp = buildTemplate(t, i); if (SALT) comp.seed = comp.seed + '-' + SALT; // fresh event content, same grammar const name = `${String(++n).padStart(2, '0')}_${t.id}_v${i + 1}`; writeFileSync(`${OUT}/${name}.svg`, renderComposition(comp, SIZE)); writeFileSync(`${OUT}/${name}.mjs`, `/* ${t.name} (${t.source}) · variation ${i + 1} */\nexport const composition = ${JSON.stringify(comp, null, 2)};\n`); items.push({ name, t, seed: comp.seed }); console.log(` ${name} ${t.name} · ${t.source} · ${comp.seed}`); } } console.log(`templates — ${n} compositions → ${OUT}/`); // plain contact sheet writeFileSync(`${OUT}/m.html`, `
Traces of the Invisible — a catalogue of compositions
the grammar of great pictures, applied to one instrument · ${n} plates${SALT ? ' · series ' + SALT : ''}