doxa-maps/library/scripts/posters/shoot.mjs
doxa-maps d5ba21fa76 doxa-maps — portable bundler for embeddable JAMstack maps
Standalone repo that builds embeddable JAMstack map bundles (web components),
composes them into a lazy-loaded SPA via layouts/, and optionally wraps a
Capacitor Android/iOS app — one build, choose your output/CDN. Diátaxis docs.

History reset to a single clean commit; no PII, IPs, or internal terms.
2026-09-10 01:53:07 +00:00

47 lines
1.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// shoot.mjs — Playwright (Firefox, NO Google Chrome) screenshots each poster
// HTML → a high-DPI PNG (3ft × 4ft @ ~150 DPI). Mirrors the vision-wall
// HTML→PNG mechanism. Pure local; no network.
//
// node shoot.mjs # all posters in out/manifest.json
// ONLY=laos node shoot.mjs # one poster
//
// deviceScaleFactor 4 over a 1350×1800 CSS poster ⇒ 5400×7200 px PNG.
import { firefox } from 'playwright';
import { readFileSync } from 'node:fs';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { dirname, join } from 'node:path';
const __dirname = dirname(fileURLToPath(import.meta.url));
const OUT = join(__dirname, 'out');
const ONLY = process.env.ONLY;
const DSF = Number(process.env.DSF || 4);
let list;
if (ONLY) {
list = [{ zoneKey: ONLY, html: `posters/${ONLY}.html`, png: `posters/${ONLY}.png` }];
} else {
const m = JSON.parse(readFileSync(join(OUT, 'manifest.json'), 'utf8'));
list = m.posters;
}
const browser = await firefox.launch();
// Viewport must be at least as large as the sheet or the .stage element screenshot
// is clipped. The sheet is no longer always 3x4 portrait (FORMAT=3x3 is 1500x1500),
// so these are overridable rather than hardcoded to the portrait dimensions.
const VW = Number(process.env.VW || 1500);
const VH = Number(process.env.VH || 1800);
const ctx = await browser.newContext({ viewport: { width: VW, height: VH }, deviceScaleFactor: DSF });
const page = await ctx.newPage();
let n = 0;
for (const p of list) {
const url = pathToFileURL(join(OUT, p.html)).href;
await page.goto(url, { waitUntil: 'load' });
await page.waitForTimeout(120);
const el = await page.$('.stage');
await el.screenshot({ path: join(OUT, p.png) });
n++;
console.log(` 📸 ${p.png}`);
}
await browser.close();
console.log(`\n${n} screenshot(s) @ dsf=${DSF} (≈${1350 * DSF}×${1800 * DSF}px)`);