From 3443c1c65e9f1753e1e656b35d08416c1fa298f2 Mon Sep 17 00:00:00 2001 From: godosa Date: Wed, 7 Oct 2026 00:14:38 +0200 Subject: worldmap-viewer: initial public history --- viewer/js/units.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 viewer/js/units.js (limited to 'viewer/js/units.js') diff --git a/viewer/js/units.js b/viewer/js/units.js new file mode 100644 index 0000000..4d9332f --- /dev/null +++ b/viewer/js/units.js @@ -0,0 +1,22 @@ +// units.js — SI ↔ optional in-world units (spans, leagues; from /api/meta at startup). Without them: SI only. +export const UNITS = { span_m: null, moment_s: null, league_km: null, day_hours: 24 }; +export function setUnits(u) { Object.assign(UNITS, u || {}); } +export const kmToLeagues = km => km / UNITS.league_km; +export const mToSpans = m => m / UNITS.span_m; +export const km2ToSqLeagues = a => a / UNITS.league_km ** 2; +export const walkDays = (km, kmPerDay = 30) => km / kmPerDay; +const num = (v, d) => v.toLocaleString('en-US', { minimumFractionDigits: d, maximumFractionDigits: d }); +const spans = m => (UNITS.span_m ? ` · ${num(mToSpans(m), 0)} spans` : ''); +const leagues = (km, d) => (UNITS.league_km ? ` · ${num(kmToLeagues(km), d)} leagues` : ''); +export const fmtDistance = km => (km < 1 + ? `${num(km * 1000, 0)} m${spans(km * 1000)}` + : `${num(km, km < 100 ? 1 : 0)} km${leagues(km, km < 100 ? 2 : 1)}`); +export const fmtElev = m => `${num(m, 0)} m${spans(m)}`; +export const fmtArea = km2 => `${num(km2, 0)} km²${UNITS.league_km ? ` · ${num(km2ToSqLeagues(km2), 0)} sq leagues` : ''}`; +export function fmtWalk(km) { const d = walkDays(km); return `${num(d, d < 10 ? 1 : 0)} days on foot`; } +export const fmtLatLon = (lat, lon) => + `${Math.abs(lat).toFixed(3)}° ${lat >= 0 ? 'N' : 'S'}, ${Math.abs(lon).toFixed(3)}° ${lon >= 0 ? 'E' : 'W'}`; +export function niceKm(km) { + const p = 10 ** Math.floor(Math.log10(km)); + return p * [1, 2, 5].findLast(m => m * p <= km * (1 + 1e-12)); +} -- cgit