Files
mapwright/dev/make-raster-test.mjs
T
slaguru666andClaude Opus 4.8 100e514c4d Mapwright v0.5.0 — procedural battle map generator for Foundry VTT
Buildings (modern/fantasy, multi-floor, footprint shapes), caves, outdoor
biomes, and town/village + city-block settlements. Auto-places Foundry walls,
doors, windows, lighting; furniture as locked tiles; live preview.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:05:25 +01:00

66 lines
3.1 KiB
JavaScript

/**
* Build an HTML harness that renders one generated SVG two ways:
* left = inline in the DOM (what the preview does — lenient HTML parser)
* right = rasterised to a <canvas> via Image (what scene.mjs does)
* Used with Playwright to reproduce the "missing content in scene" bug.
*/
import { writeFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import { Rng } from "../module/lib/rng.mjs";
import { generateBuilding } from "../module/lib/building.mjs";
import { buildWalls } from "../module/lib/walls.mjs";
import { renderSVG } from "../module/lib/render-vector.mjs";
const here = dirname(fileURLToPath(import.meta.url));
const layout = generateBuilding({ cols: 26, rows: 18, targetRooms: 11, subtype: "modern", seed: "mire-680", shape: "rectangle" });
const walls = buildWalls(layout, { rng: new Rng("mire-680::walls::0") });
const svg = renderSVG({ layout, walls, gridSize: 100, subtype: "modern", seed: "mire-680::0" });
const W = layout.cols * 100, H = layout.rows * 100;
const html = `<!doctype html><html><head><meta charset="utf-8"><style>
body{margin:0;background:#444;font-family:sans-serif;color:#fff}
.row{display:flex;gap:8px;padding:8px}
.cell{flex:1}.cell h3{margin:4px}
svg,canvas{width:100%;height:auto;border:1px solid #000;background:#888}
</style></head><body>
<div class="row">
<div class="cell"><h3>A: inline SVG (preview)</h3><div id="inline">${svg}</div></div>
<div class="cell"><h3 id="status">B: SVG→canvas</h3><canvas id="cv" width="${W}" height="${H}"></canvas></div>
<div class="cell"><h3 id="status2">C: →PNG blob→reload (final scene bytes)</h3><canvas id="cv2" width="${W}" height="${H}"></canvas></div>
</div>
<script>
const svgText = ${JSON.stringify(svg)};
const W=${W}, H=${H};
const blob = new Blob([svgText], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(blob);
const img = new Image(); img.width=W; img.height=H;
img.onload = async () => {
try { if (img.decode) await img.decode(); } catch(e){}
const cv = document.getElementById("cv");
cv.getContext("2d").drawImage(img, 0, 0, W, H);
document.getElementById("status").textContent = "B: SVG→canvas — OK";
// C: exactly what scene.mjs uploads — toBlob PNG, then reload it
cv.toBlob((png) => {
if (!png) { document.getElementById("status2").textContent = "C: toBlob NULL"; window.__done = true; return; }
const purl = URL.createObjectURL(png);
const img2 = new Image();
img2.onload = () => {
document.getElementById("cv2").getContext("2d").drawImage(img2, 0, 0, W, H);
document.getElementById("status2").textContent = "C: PNG " + Math.round(png.size/1024) + "KB — OK";
window.__done = true;
};
img2.onerror = () => { document.getElementById("status2").textContent = "C: PNG RELOAD ERROR"; window.__done = true; };
img2.src = purl;
}, "image/png");
};
img.onerror = (e) => { document.getElementById("status").textContent = "B: IMAGE ERROR"; window.__done = true; };
img.src = url;
</script>
</body></html>`;
writeFileSync(join(here, "raster-test.html"), html);
console.log("wrote", join(here, "raster-test.html"), "size", svg.length);