mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-04-04 22:47:23 +02:00
fix: clean up drawWebGl and drawSvg functions for improved readability
This commit is contained in:
parent
ab7baf83fd
commit
828534ebd9
2 changed files with 15 additions and 131 deletions
|
|
@ -1,139 +1,28 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate pre-rasterised PNG sprite atlases for the three relief icon sets
|
* Generate pre-rasterised PNG sprite atlases for the relief icon sets.
|
||||||
* (simple, gray, colored) from the SVG <symbol> definitions in src/index.html.
|
|
||||||
*
|
|
||||||
* Output: public/images/relief/{simple,gray,colored}.png
|
* Output: public/images/relief/{simple,gray,colored}.png
|
||||||
*
|
*
|
||||||
* Each atlas is a grid of SPRITE_SIZE × SPRITE_SIZE tiles arranged
|
* Each atlas is a grid of SPRITE_SIZE × SPRITE_SIZE tiles arranged
|
||||||
* left-to-right, top-to-bottom. Tile order matches the SET_SYMBOLS arrays
|
* left-to-right, top-to-bottom. Tile order matches the RELIEF_SYMBOLS.
|
||||||
* in src/renderers/draw-relief-icons.ts — keep the two in sync.
|
|
||||||
*
|
*
|
||||||
* Rendering strategy: each symbol is placed as a standalone <svg> element
|
* Run: `node scripts/generate-relief-atlases.js`
|
||||||
* positioned in a CSS grid inside a regular HTML page, then Playwright's
|
|
||||||
* native page.screenshot() captures the result. This avoids the headless-
|
|
||||||
* Chromium restriction that prevents SVG blob/data URLs from rendering when
|
|
||||||
* drawn to a <canvas> element.
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* node scripts/generate-relief-atlases.js
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const {chromium} = require("playwright");
|
const {chromium} = require("playwright");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const {RELIEF_SYMBOLS} = require("../src/config/relief-config.ts");
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Configuration — keep in sync with SET_SYMBOLS in draw-relief-icons.ts
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const SPRITE_SIZE = 512; // px per symbol tile
|
const SPRITE_SIZE = 512; // px per symbol tile
|
||||||
|
|
||||||
const SET_SYMBOLS = {
|
|
||||||
simple: [
|
|
||||||
"relief-mount-1",
|
|
||||||
"relief-hill-1",
|
|
||||||
"relief-conifer-1",
|
|
||||||
"relief-deciduous-1",
|
|
||||||
"relief-acacia-1",
|
|
||||||
"relief-palm-1",
|
|
||||||
"relief-grass-1",
|
|
||||||
"relief-swamp-1",
|
|
||||||
"relief-dune-1"
|
|
||||||
],
|
|
||||||
gray: [
|
|
||||||
"relief-mount-2-bw",
|
|
||||||
"relief-mount-3-bw",
|
|
||||||
"relief-mount-4-bw",
|
|
||||||
"relief-mount-5-bw",
|
|
||||||
"relief-mount-6-bw",
|
|
||||||
"relief-mount-7-bw",
|
|
||||||
"relief-mountSnow-1-bw",
|
|
||||||
"relief-mountSnow-2-bw",
|
|
||||||
"relief-mountSnow-3-bw",
|
|
||||||
"relief-mountSnow-4-bw",
|
|
||||||
"relief-mountSnow-5-bw",
|
|
||||||
"relief-mountSnow-6-bw",
|
|
||||||
"relief-hill-2-bw",
|
|
||||||
"relief-hill-3-bw",
|
|
||||||
"relief-hill-4-bw",
|
|
||||||
"relief-hill-5-bw",
|
|
||||||
"relief-conifer-2-bw",
|
|
||||||
"relief-coniferSnow-1-bw",
|
|
||||||
"relief-swamp-2-bw",
|
|
||||||
"relief-swamp-3-bw",
|
|
||||||
"relief-cactus-1-bw",
|
|
||||||
"relief-cactus-2-bw",
|
|
||||||
"relief-cactus-3-bw",
|
|
||||||
"relief-deadTree-1-bw",
|
|
||||||
"relief-deadTree-2-bw",
|
|
||||||
"relief-vulcan-1-bw",
|
|
||||||
"relief-vulcan-2-bw",
|
|
||||||
"relief-vulcan-3-bw",
|
|
||||||
"relief-dune-2-bw",
|
|
||||||
"relief-grass-2-bw",
|
|
||||||
"relief-acacia-2-bw",
|
|
||||||
"relief-palm-2-bw",
|
|
||||||
"relief-deciduous-2-bw",
|
|
||||||
"relief-deciduous-3-bw"
|
|
||||||
],
|
|
||||||
colored: [
|
|
||||||
"relief-mount-2",
|
|
||||||
"relief-mount-3",
|
|
||||||
"relief-mount-4",
|
|
||||||
"relief-mount-5",
|
|
||||||
"relief-mount-6",
|
|
||||||
"relief-mount-7",
|
|
||||||
"relief-mountSnow-1",
|
|
||||||
"relief-mountSnow-2",
|
|
||||||
"relief-mountSnow-3",
|
|
||||||
"relief-mountSnow-4",
|
|
||||||
"relief-mountSnow-5",
|
|
||||||
"relief-mountSnow-6",
|
|
||||||
"relief-hill-2",
|
|
||||||
"relief-hill-3",
|
|
||||||
"relief-hill-4",
|
|
||||||
"relief-hill-5",
|
|
||||||
"relief-conifer-2",
|
|
||||||
"relief-coniferSnow-1",
|
|
||||||
"relief-swamp-2",
|
|
||||||
"relief-swamp-3",
|
|
||||||
"relief-cactus-1",
|
|
||||||
"relief-cactus-2",
|
|
||||||
"relief-cactus-3",
|
|
||||||
"relief-deadTree-1",
|
|
||||||
"relief-deadTree-2",
|
|
||||||
"relief-vulcan-1",
|
|
||||||
"relief-vulcan-2",
|
|
||||||
"relief-vulcan-3",
|
|
||||||
"relief-dune-2",
|
|
||||||
"relief-grass-2",
|
|
||||||
"relief-acacia-2",
|
|
||||||
"relief-palm-2",
|
|
||||||
"relief-deciduous-2",
|
|
||||||
"relief-deciduous-3"
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Paths
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const ROOT = path.resolve(__dirname, "..");
|
const ROOT = path.resolve(__dirname, "..");
|
||||||
const INDEX_HTML = path.join(ROOT, "src", "index.html");
|
const INDEX_HTML = path.join(ROOT, "src", "index.html");
|
||||||
const OUTPUT_DIR = path.join(ROOT, "public", "images", "relief");
|
const OUTPUT_DIR = path.join(ROOT, "public", "images", "relief");
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Extract every <symbol id="relief-*"> element from index.html
|
|
||||||
// Returns a map of symbolId → {viewBox, innerSvg}
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function extractSymbols(html) {
|
function extractSymbols(html) {
|
||||||
const symbols = {};
|
const symbols = {};
|
||||||
// Match each <symbol ...>...</symbol> block.
|
|
||||||
// <symbol> elements never nest, so a lazy [\s\S]*? is safe here.
|
|
||||||
const re = /<symbol\s([^>]+)>([\s\S]*?)<\/symbol>/g;
|
const re = /<symbol\s([^>]+)>([\s\S]*?)<\/symbol>/g;
|
||||||
let m;
|
let m;
|
||||||
while ((m = re.exec(html)) !== null) {
|
while ((m = re.exec(html)) !== null) {
|
||||||
|
|
@ -164,24 +53,18 @@ console.log(`Extracted ${found} relief symbols from index.html`);
|
||||||
|
|
||||||
fs.mkdirSync(OUTPUT_DIR, {recursive: true});
|
fs.mkdirSync(OUTPUT_DIR, {recursive: true});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Main — render each atlas via Playwright's native screenshot
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const browser = await chromium.launch();
|
const browser = await chromium.launch();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
||||||
for (const [set, ids] of Object.entries(SET_SYMBOLS)) {
|
for (const [set, ids] of Object.entries(RELIEF_SYMBOLS)) {
|
||||||
const n = ids.length;
|
const n = ids.length;
|
||||||
const cols = Math.ceil(Math.sqrt(n));
|
const cols = Math.ceil(Math.sqrt(n));
|
||||||
const rows = Math.ceil(n / cols);
|
const rows = Math.ceil(n / cols);
|
||||||
const W = cols * SPRITE_SIZE;
|
const W = cols * SPRITE_SIZE;
|
||||||
const H = rows * SPRITE_SIZE;
|
const H = rows * SPRITE_SIZE;
|
||||||
|
|
||||||
// Build one SVG per symbol, absolutely positioned in a grid.
|
// Build one SVG per symbol, absolutely positioned in a grid
|
||||||
// Using standalone <svg> elements (not <use>) means the symbols are
|
|
||||||
// self-contained and render correctly regardless of CSP restrictions.
|
|
||||||
const svgTiles = ids
|
const svgTiles = ids
|
||||||
.map((symbolId, idx) => {
|
.map((symbolId, idx) => {
|
||||||
const sym = allSymbols[symbolId];
|
const sym = allSymbols[symbolId];
|
||||||
|
|
|
||||||
|
|
@ -233,8 +233,6 @@ function renderFrame(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawWebGl(icons: ReliefIcon[], parentEl: HTMLElement): void {
|
function drawWebGl(icons: ReliefIcon[], parentEl: HTMLElement): void {
|
||||||
parentEl.innerHTML = "";
|
|
||||||
parentEl.dataset.mode = "webGL";
|
|
||||||
const set = parentEl.getAttribute("set") || "simple";
|
const set = parentEl.getAttribute("set") || "simple";
|
||||||
|
|
||||||
if (ensureRenderer()) {
|
if (ensureRenderer()) {
|
||||||
|
|
@ -248,12 +246,12 @@ function drawWebGl(icons: ReliefIcon[], parentEl: HTMLElement): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawSvg(icons: ReliefIcon[], parentEl: HTMLElement): void {
|
function drawSvg(icons: ReliefIcon[], parentEl: HTMLElement): void {
|
||||||
const html = icons.map(
|
parentEl.innerHTML = icons
|
||||||
(r) =>
|
.map(
|
||||||
`<use href="${r.href}" data-id="${r.i}" x="${r.x}" y="${r.y}" width="${r.s}" height="${r.s}"/>`,
|
(r) =>
|
||||||
);
|
`<use href="${r.href}" data-id="${r.i}" x="${r.x}" y="${r.y}" width="${r.s}" height="${r.s}"/>`,
|
||||||
parentEl.innerHTML = html.join("");
|
)
|
||||||
parentEl.dataset.mode = "svg";
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
window.drawRelief = (
|
window.drawRelief = (
|
||||||
|
|
@ -262,6 +260,9 @@ window.drawRelief = (
|
||||||
) => {
|
) => {
|
||||||
if (!parentEl) throw new Error("Relief: parent element not found");
|
if (!parentEl) throw new Error("Relief: parent element not found");
|
||||||
|
|
||||||
|
parentEl.innerHTML = "";
|
||||||
|
parentEl.dataset.mode = "webGL";
|
||||||
|
|
||||||
const icons = pack.relief?.length ? pack.relief : generateRelief();
|
const icons = pack.relief?.length ? pack.relief : generateRelief();
|
||||||
if (!icons.length) return;
|
if (!icons.length) return;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue