43 lines
2.6 KiB
JavaScript
43 lines
2.6 KiB
JavaScript
// Contact sheets for visual review of a previously generated static theme matrix.
|
|
// node scripts/theme-matrix-gallery.mjs [matrixDir] [mode] [width]
|
|
import { readFile, mkdir, writeFile } from 'node:fs/promises';
|
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
import { join } from 'node:path';
|
|
import { chromium } from 'playwright';
|
|
|
|
const root = fileURLToPath(new URL('../', import.meta.url));
|
|
const matrix = process.argv[2] ?? join(root, '../../verification/theme-matrix/current-full');
|
|
const mode = process.argv[3] ?? 'dark';
|
|
const width = Number(process.argv[4] ?? 1280);
|
|
const rows = JSON.parse(await readFile(join(matrix, 'results.json'), 'utf8')).results.filter(r => r.mode === mode && r.width === width && r.shot);
|
|
const cells = [...new Set(rows.map(r => r.cell))];
|
|
const themes = [...new Set(rows.map(r => r.theme))];
|
|
const out = join(matrix, 'gallery');
|
|
await mkdir(out, { recursive: true });
|
|
const browser = await chromium.launch({ headless: true });
|
|
let sheet = 0;
|
|
try {
|
|
const page = await browser.newPage({ viewport: { width: 1700, height: 1000 }, deviceScaleFactor: 1 });
|
|
for (let ci = 0; ci < cells.length; ci += 4) {
|
|
for (let ti = 0; ti < themes.length; ti += 7) {
|
|
const subsetCells = cells.slice(ci, ci + 4), subsetThemes = themes.slice(ti, ti + 7);
|
|
const cards = subsetCells.flatMap(cell => subsetThemes.map(theme => {
|
|
const r = rows.find(x => x.cell === cell && x.theme === theme);
|
|
return `<figure><figcaption>${cell} · ${theme}</figcaption><img src="../${r.shot}"></figure>`;
|
|
})).join('');
|
|
const html = `<!doctype html><meta charset="utf-8"><style>
|
|
body{margin:0;padding:12px;background:#191919;color:#fff;font:12px system-ui}
|
|
.grid{display:grid;grid-template-columns:repeat(7,230px);gap:8px}
|
|
figure{margin:0;background:#292929;border:1px solid #555;padding:3px}
|
|
figcaption{height:20px;white-space:nowrap;overflow:hidden}
|
|
img{display:block;width:220px;height:155px;object-fit:contain;background:#111}
|
|
</style><h2>${mode} ${width} · pages ${ci+1}-${Math.min(ci+4,cells.length)} · themes ${ti+1}-${Math.min(ti+7,themes.length)}</h2><div class="grid">${cards}</div>`;
|
|
const file = join(out, `sheet-${String(++sheet).padStart(2, '0')}.html`);
|
|
await writeFile(file, html);
|
|
await page.goto(pathToFileURL(file).href);
|
|
await page.locator('img').first().waitFor();
|
|
await page.screenshot({ path: file.replace(/\.html$/, '.png'), fullPage: true });
|
|
}
|
|
}
|
|
} finally { await browser.close(); }
|
|
console.log(`${cells.length} page/layer families × ${themes.length} themes at ${mode}/${width}; ${sheet} contact sheets in ${out}`);
|