#!/usr/bin/env node // Erzeugt die HUD-Renderings für die README aus denselben Werten wie nui/style.css. // Keine In-Game-Screenshots - eine massstabsgetreue Nachbildung des Overlays. // // Nutzung: node docs/gen-hud-svg.mjs [ziel-ordner] (default: docs) import { writeFileSync, mkdirSync } from 'node:fs'; import { join } from 'node:path'; const OUT = process.argv[2] ?? 'docs'; mkdirSync(OUT, { recursive: true }); const C = { accent: '#38bdf8', warn: '#fbbf24', danger: '#f87171', text: '#e2e8f0', muted: '#94a3b8', panel: '#09121c', border: '#94a3b8' }; // Geometrie spiegelt das Grid aus style.css: // padding 14/22, Spalten 84 | 92 | 84 mit column-gap 22, row-gap 8, Lampe 23 hoch. const PAD_X = 22, PAD_Y = 14, COL = 84, GAUGE = 92, GAP = 22, ROW_GAP = 8, LAMP_H = 23; const PW = PAD_X * 2 + COL * 2 + GAUGE + GAP * 2; const PH = PAD_Y * 2 + GAUGE + ROW_GAP + LAMP_H; const W = 520, H = PH + 70; const PX = (W - PW) / 2, PY = (H - PH) / 2; const GX = PX + PAD_X + COL + GAP; const CX = GX + GAUGE / 2, CY = PY + PAD_Y + GAUGE / 2; const R = 52 * (GAUGE / 120); // r=52 im viewBox 120, auf 92px skaliert const SW = 8 * (GAUGE / 120); const CIRC = 2 * Math.PI * R; const DEPTH_X = PX + PAD_X + COL; // rechtsbündig, zeigt zum Ring const PRESS_X = GX + GAUGE + GAP; // linksbündig, zeigt zum Ring const CAP_Y = PY + PAD_Y + 35; const VAL_Y = PY + PAD_Y + 61; const FONT = "'Segoe UI',Roboto,system-ui,sans-serif"; const fmt = (s) => `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(Math.floor(s % 60)).padStart(2, '0')}`; function readout(x, anchor, label, value, unit, colour) { const unitTspan = `${unit}`; return `${label} ${value}${unitTspan}`; } function build({ file, title, oxygen, capacity, depth, pressure, level, deep, reserve, lamp }) { const ratio = Math.max(0, Math.min(1, oxygen / capacity)); const ring = level === 'danger' ? C.danger : level === 'warn' ? C.warn : C.accent; const lampColour = lamp ? C.accent : C.muted; const lampX = CX - 43; const svg = ` ${fmt(oxygen)} LUFT ${readout(DEPTH_X, 'end', 'TIEFE', depth.toFixed(1), 'm', deep ? C.warn : C.text)} ${readout(PRESS_X, 'start', 'DRUCK', String(Math.round(pressure)), 'bar', reserve ? C.danger : C.text)} LAMPE `; writeFileSync(join(OUT, file), svg); console.log(file); } build({ file: 'hud-normal.svg', title: 'Tauch-HUD: normaler Zustand', oxygen: 545, capacity: 1200, depth: 12.4, pressure: 136, level: 'ok', lamp: true }); build({ file: 'hud-warnung.svg', title: 'Tauch-HUD: Warnstufe und Reservedruck', oxygen: 92, capacity: 900, depth: 27.5, pressure: 31, level: 'warn', deep: true, reserve: true, lamp: false }); build({ file: 'hud-kritisch.svg', title: 'Tauch-HUD: kritischer Luftstand', oxygen: 8, capacity: 600, depth: 31.7, pressure: 4, level: 'danger', deep: true, reserve: true, lamp: true });