diff --git a/index.html b/index.html index 92a3aee..ca31536 100644 --- a/index.html +++ b/index.html @@ -1,43 +1,150 @@ - - + + ⚡️ Core Game Visualizer + - +
+ + + -
-
- +
+
+
- +
- - + +
-
- - - + +
+ + +
-
- + +
+
- +
- - + +
+ + +
@@ -65,10 +172,6 @@

- -
diff --git a/package.json b/package.json index fa983b7..70890e1 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "fireworks-js": "^2.10.8" }, "lint-staged": { - "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [ + "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,css}": [ "biome check --write --no-errors-on-unmatched" ] } diff --git a/public/assets/object-svgs/bomb.svg b/public/assets/object-svgs/bomb.svg index 6d59085..4dfb5ea 100644 --- a/public/assets/object-svgs/bomb.svg +++ b/public/assets/object-svgs/bomb.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/cores/1.svg b/public/assets/object-svgs/cores/1.svg index 19dd949..7262d2e 100644 --- a/public/assets/object-svgs/cores/1.svg +++ b/public/assets/object-svgs/cores/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/cores/2.svg b/public/assets/object-svgs/cores/2.svg index 43750f3..d82c064 100644 --- a/public/assets/object-svgs/cores/2.svg +++ b/public/assets/object-svgs/cores/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/resource.svg b/public/assets/object-svgs/resource.svg index 15d212a..60e3b0a 100644 --- a/public/assets/object-svgs/resource.svg +++ b/public/assets/object-svgs/resource.svg @@ -14,9 +14,6 @@ id="defs2" /> diff --git a/public/assets/object-svgs/units/builder/1.svg b/public/assets/object-svgs/units/builder/1.svg index 910d4c4..9c4824a 100644 --- a/public/assets/object-svgs/units/builder/1.svg +++ b/public/assets/object-svgs/units/builder/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/builder/2.svg b/public/assets/object-svgs/units/builder/2.svg index 5a35057..6152bf5 100644 --- a/public/assets/object-svgs/units/builder/2.svg +++ b/public/assets/object-svgs/units/builder/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/carrier/1.svg b/public/assets/object-svgs/units/carrier/1.svg index 5fccfb3..cee179d 100644 --- a/public/assets/object-svgs/units/carrier/1.svg +++ b/public/assets/object-svgs/units/carrier/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/carrier/2.svg b/public/assets/object-svgs/units/carrier/2.svg index ff87f4b..a953ee5 100644 --- a/public/assets/object-svgs/units/carrier/2.svg +++ b/public/assets/object-svgs/units/carrier/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/miner/1.svg b/public/assets/object-svgs/units/miner/1.svg index f2ad10c..19c0edb 100644 --- a/public/assets/object-svgs/units/miner/1.svg +++ b/public/assets/object-svgs/units/miner/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/miner/2.svg b/public/assets/object-svgs/units/miner/2.svg index ac26189..74af943 100644 --- a/public/assets/object-svgs/units/miner/2.svg +++ b/public/assets/object-svgs/units/miner/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/tank/1.svg b/public/assets/object-svgs/units/tank/1.svg index 871a0c5..f9a33a1 100644 --- a/public/assets/object-svgs/units/tank/1.svg +++ b/public/assets/object-svgs/units/tank/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/tank/2.svg b/public/assets/object-svgs/units/tank/2.svg index fffaab5..e55c37a 100644 --- a/public/assets/object-svgs/units/tank/2.svg +++ b/public/assets/object-svgs/units/tank/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/warrior/1.svg b/public/assets/object-svgs/units/warrior/1.svg index 45ad532..5dee38d 100644 --- a/public/assets/object-svgs/units/warrior/1.svg +++ b/public/assets/object-svgs/units/warrior/1.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/units/warrior/2.svg b/public/assets/object-svgs/units/warrior/2.svg index 52cd1cc..aacbd38 100644 --- a/public/assets/object-svgs/units/warrior/2.svg +++ b/public/assets/object-svgs/units/warrior/2.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/object-svgs/wall.svg b/public/assets/object-svgs/wall.svg index ec1f5ac..3796566 100644 --- a/public/assets/object-svgs/wall.svg +++ b/public/assets/object-svgs/wall.svg @@ -15,9 +15,6 @@ id="defs1" /> diff --git a/public/assets/ui-svgs/core-logo.svg b/public/assets/ui-svgs/core-logo.svg index ab8d69a..d4333e0 100644 --- a/public/assets/ui-svgs/core-logo.svg +++ b/public/assets/ui-svgs/core-logo.svg @@ -1,6 +1,5 @@ diff --git a/public/assets/ui-svgs/dark-mode-moon.svg b/public/assets/ui-svgs/dark-mode-moon.svg new file mode 100644 index 0000000..0fadbe0 --- /dev/null +++ b/public/assets/ui-svgs/dark-mode-moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/ui-svgs/dark-mode-sun.svg b/public/assets/ui-svgs/dark-mode-sun.svg new file mode 100644 index 0000000..e5b25b6 --- /dev/null +++ b/public/assets/ui-svgs/dark-mode-sun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/ui-svgs/github-logo.svg b/public/assets/ui-svgs/github-logo.svg index d5e6491..99c1a1b 100644 --- a/public/assets/ui-svgs/github-logo.svg +++ b/public/assets/ui-svgs/github-logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/assets/ui-svgs/pause.svg b/public/assets/ui-svgs/pause.svg index f78e5c1..bafcfde 100644 --- a/public/assets/ui-svgs/pause.svg +++ b/public/assets/ui-svgs/pause.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/play.svg b/public/assets/ui-svgs/play.svg index 566dacb..915c223 100644 --- a/public/assets/ui-svgs/play.svg +++ b/public/assets/ui-svgs/play.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/skip_end.svg b/public/assets/ui-svgs/skip_end.svg index ea4913f..33a23a8 100644 --- a/public/assets/ui-svgs/skip_end.svg +++ b/public/assets/ui-svgs/skip_end.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/skip_start.svg b/public/assets/ui-svgs/skip_start.svg index 0b1c2a6..a7ac94e 100644 --- a/public/assets/ui-svgs/skip_start.svg +++ b/public/assets/ui-svgs/skip_start.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/speed_down.svg b/public/assets/ui-svgs/speed_down.svg index 0dcd517..201518e 100644 --- a/public/assets/ui-svgs/speed_down.svg +++ b/public/assets/ui-svgs/speed_down.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/speed_up.svg b/public/assets/ui-svgs/speed_up.svg index 3f6d0ff..8993c19 100644 --- a/public/assets/ui-svgs/speed_up.svg +++ b/public/assets/ui-svgs/speed_up.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/tick_next.svg b/public/assets/ui-svgs/tick_next.svg index 3b486d0..cc2ab6d 100644 --- a/public/assets/ui-svgs/tick_next.svg +++ b/public/assets/ui-svgs/tick_next.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/public/assets/ui-svgs/tick_previous.svg b/public/assets/ui-svgs/tick_previous.svg index bb25fb1..6240e7b 100644 --- a/public/assets/ui-svgs/tick_previous.svg +++ b/public/assets/ui-svgs/tick_previous.svg @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/src/css/styles.css b/src/css/styles.css index e612cfc..0a79a48 100644 --- a/src/css/styles.css +++ b/src/css/styles.css @@ -5,11 +5,64 @@ } :root { + --svg-canvas-scale: 100%; + + --core-purple: #6a0dad; +} +:root[data-theme="light"] { --hp-color: #c70202ff; --balance-color: #008600ff; --cooldown-color: #0066ffff; - --svg-canvas-scale: 100%; - --core-purple: #6a0dad; + + --panel-bg: color-mix(in srgb, var(--core-purple) 7%, white); + --panel-outline: color-mix(in srgb, var(--core-purple) 50%, white); + --panel-track: #a4a4a4; + --panel-thumb: var(--core-purple); + + --text: #333333; + --tooltip-shadow-contrast: #ffffff; + + --app-bg: color-mix(in srgb, var(--core-purple) 25%, white); + --grid-bg: var(--panel-bg); + + --corner-buttons-color: var(--core-purple); + + --svg-icon-fill: #000000; + + --fireworks-darkening-layer: rgba(0, 0, 0, 0.75); +} +:root[data-theme="dark"] { + --hp-color: rgb(242, 12, 12); + --balance-color: rgb(0, 215, 0); + --cooldown-color: #0066ffff; + + --panel-bg: #4d4d73; + --panel-outline: #9f9fe3; + --panel-track: #6f6fd6; + --panel-thumb: color-mix(in srgb, var(--core-purple) 30%, white); + + --text: #e8e8ea; + --tooltip-shadow-contrast: #000000; + + --app-bg: color-mix(in srgb, var(--core-purple) 40%, black); + --grid-bg: color-mix(in srgb, var(--panel-bg) 50%, black); + + --corner-buttons-color: color-mix(in srgb, var(--core-purple) 35%, white); + + --svg-icon-fill: #ffffff; + + --fireworks-darkening-layer: rgba(0, 0, 0, 0.5); +} + +:root[data-theme="dark"] .game-object { + filter: invert(100%) sepia(96%) saturate(17%) hue-rotate(214deg) + brightness(104%) contrast(100); +} +:root[data-theme="light"] .game-object.team-1 { + opacity: 0.5; +} +:root[data-theme="dark"] .game-object.team-1 { + opacity: 0.7; } html, @@ -20,20 +73,49 @@ body { overflow: hidden; overscroll-behavior: none; font-family: "JetBrains Mono", monospace; - background-color: color-mix(in srgb, var(--core-purple) 20%, white); + color: var(--text); + background-color: var(--app-bg); } /* SVG Output Canvas */ +#svg-canvas { + width: var(--svg-canvas-scale); + height: var(--svg-canvas-scale); + aspect-ratio: 1 / 1; + outline: 2px solid var(--panel-outline); + background-color: var(--grid-bg); + border-radius: 10px; + margin: 10px 0 10px 0; + color: var(--svg-icon-fill); +} + +.grid-cell { + fill: var(--grid-bg); + pointer-events: none; +} + #tooltip { position: fixed; display: none; padding: 10px; - background: white; - border: 1px solid #333; + background: var(--panel-bg); + border: 1px solid var(--panel-outline); border-radius: 0 10px 10px 10px; box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3); + color: var(--text); pointer-events: none; } +#tooltip span[style*="var(--hp-color)"], +#tooltip span[style*="var(--balance-color)"], +#tooltip span[style*="var(--cooldown-color)"] { + text-shadow: + 0 0 2px var(--tooltip-shadow-contrast), + 0 0 4px var(--tooltip-shadow-contrast); +} + +svg path { + fill: var(--svg-icon-fill); +} /* Structure */ .container { @@ -58,53 +140,73 @@ body { .teamName { font-size: 1.5rem; font-weight: bold; - color: #333; + color: var(--text); text-align: center; - background-color: #f0f0f0; + background-color: var(--panel-bg); + outline: 2px solid var(--panel-outline); padding: 0.5rem 1rem; margin: 10px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - outline: 2px solid #ccc; -} - -#svg-canvas { - width: var(--svg-canvas-scale); - height: var(--svg-canvas-scale); - aspect-ratio: 1 / 1; - outline: 2px solid #ccc; - background-color: #f9f9f9; - border-radius: 10px; - margin: 10px 0 10px 0; } /* Time Controls */ -#time-controls { +.control-panel { display: flex; align-items: center; - justify-content: space-between; - gap: 1rem; + justify-content: center; + gap: 3.5rem; padding: 0.5rem 1rem; - background-color: #f0f0f0; + background-color: var(--panel-bg); border-radius: 0 0 20px 20px; - z-index: 5000; + outline: 2px solid var(--panel-outline); width: max-content; margin: 0 auto; - position: relative; - outline: #ccc solid 2px; + z-index: 5000; } -.controls-bar, -.main-buttons { +.control-row { display: flex; align-items: center; gap: 0.5rem; - margin: 0 20px 0 20px; + margin: 0; + flex-wrap: nowrap; } -.main-buttons button { - padding: 0.75rem; - background-color: #555; +.control-panel button { + background: none; + border: none; + cursor: pointer; + padding: 0.5rem; + border-radius: 4px; +} + +.icon-button img { + width: 1.5rem; + height: 1.5rem; + display: block; +} + +.control-panel button img { + width: 1.5rem; + height: auto; +} + +:root[data-theme="light"] .control-panel button.active, +:root[data-theme="light"] .control-panel button:active { + background-color: color-mix(in srgb, var(--core-purple) 30%, white); +} +:root[data-theme="dark"] .control-panel button.active, +:root[data-theme="dark"] .control-panel button:active { + background-color: color-mix(in srgb, var(--core-purple) 80%, black); +} +:root[data-theme="light"] .icon-button.active, +:root[data-theme="light"] .icon-button:active { + background-color: color-mix(in srgb, var(--core-purple) 30%, white); +} +:root[data-theme="dark"] .icon-button.active, +:root[data-theme="dark"] .icon-button:active { + background-color: color-mix(in srgb, var(--core-purple) 80%, black); } .slider-group { @@ -112,9 +214,10 @@ body { flex-direction: column; align-items: center; gap: 2px; - width: 6rem; + width: 7rem; box-sizing: border-box; } + .slider-group label { width: 100%; font-size: 0.9rem; @@ -127,76 +230,83 @@ body { text-overflow: ellipsis; } -#time-controls button { - background: none; - border: none; - cursor: pointer; - padding: 0.5rem; +.control-panel input[type="number"] { + width: 3.25rem; + color: var(--text); + background: var(--panel-bg); + border: 1px solid var(--panel-outline); border-radius: 4px; -} -#time-controls button:active, -#time-controls button.active { - background-color: color-mix(in srgb, var(--core-purple) 40%, white); -} - -#time-controls button img { - width: 1.5rem; - height: auto; + padding: 0.25rem 0.35rem; } -#time-controls input[type="range"] { +.control-panel input[type="range"] { -webkit-appearance: none; appearance: none; - width: 6rem; + width: 7rem; height: 0.5rem; - background: #a4a4a4; + background: var(--panel-track); border-radius: 0.25rem; } -#time-controls input[type="range"]::-webkit-slider-runnable-track { +.control-panel input[type="range"]::-webkit-slider-runnable-track { height: 100%; - background: #a4a4a4; + background: var(--panel-track); border-radius: 0.25rem; } -#time-controls input[type="range"]::-webkit-slider-thumb { +.control-panel input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 1rem; height: 1rem; margin-top: -0.25rem; - background: var(--core-purple); + background: var(--panel-thumb); border-radius: 50%; cursor: pointer; } -#time-controls input[type="range"] { - -moz-appearance: none; - appearance: none; -} - -#time-controls input[type="range"]::-moz-range-track { +.control-panel input[type="range"]::-moz-range-track { height: 0.5rem; - background: #ddd; + background: var(--panel-track); border-radius: 0.25rem; } -#time-controls input[type="range"]::-moz-range-progress { - background: var(--core-purple); +.control-panel input[type="range"]::-moz-range-progress { + background: var(--panel-thumb); height: 0.5rem; border-radius: 0.25rem; } -#time-controls input[type="range"]::-moz-range-thumb { +.control-panel input[type="range"]::-moz-range-thumb { width: 1rem; height: 1rem; - background: var(--core-purple); + background: var(--panel-thumb); border: none; border-radius: 50%; cursor: pointer; } -#time-controls input[type="number"] { - width: 3rem; +.top-bar { + display: grid; + grid-template-columns: auto max-content auto; + align-items: start; + justify-content: center; + gap: 0.5rem; + padding: 0; + z-index: 5000; +} + +.icon-button { + padding: 0.5rem 0.6rem; + background-color: var(--panel-bg); + outline: 2px solid var(--panel-outline); + border: none; + border-radius: 0 0 12px 12px; + cursor: pointer; +} + +:root[data-theme="dark"] .icon-button img, +:root[data-theme="dark"] .control-panel button img { + filter: invert(1); } /* corner buttons */ @@ -205,7 +315,7 @@ body { position: absolute; width: 7rem; height: 7rem; - background-color: var(--core-purple); + background-color: var(--corner-buttons-color); background-size: 40%; background-repeat: no-repeat; transition: transform 0.1s ease-in-out; @@ -218,20 +328,42 @@ body { #corner-bottom-left { bottom: 0; left: 0; - background-image: url("/assets/ui-svgs/github-logo.svg"); clip-path: polygon(0 100%, 0 0, 100% 100%); - background-position: 17% 83%; transform-origin: bottom left; } +#corner-bottom-left::after { + content: ""; + position: absolute; + inset: 0; + background-image: url("/assets/ui-svgs/github-logo.svg"); + background-size: 40%; + background-repeat: no-repeat; + background-position: 17% 83%; + pointer-events: none; +} +:root[data-theme="light"] #corner-bottom-left::after { + filter: invert(1); +} #corner-top-right { top: 0; right: 0; - background-image: url("/assets/ui-svgs/core-logo.svg"); clip-path: polygon(0 0, 100% 0, 100% 100%); - background-position: 83% 17%; transform-origin: top right; } +#corner-top-right::after { + content: ""; + position: absolute; + inset: 0; + background-image: url("/assets/ui-svgs/core-logo.svg"); + background-size: 40%; + background-repeat: no-repeat; + background-position: 83% 17%; + pointer-events: none; +} +:root[data-theme="light"] #corner-top-right::after { + filter: invert(1); +} /* Winner Display */ @@ -259,7 +391,7 @@ body { left: 0; width: 100vw; height: 100vh; - background-color: rgba(0, 0, 0, 0.75); + background-color: var(--fireworks-darkening-layer); z-index: 500; pointer-events: none; } diff --git a/src/ts/input_manager/themeManager.ts b/src/ts/input_manager/themeManager.ts new file mode 100644 index 0000000..ed7cc0e --- /dev/null +++ b/src/ts/input_manager/themeManager.ts @@ -0,0 +1,70 @@ +type ThemeMode = "light" | "dark"; + +const themeToggleButton = document.getElementById( + "theme-toggle-button", +) as HTMLButtonElement | null; +const themeIcon = document.getElementById( + "theme-icon", +) as HTMLImageElement | null; + +const STORAGE_KEY = "ui.theme"; +const mql = window.matchMedia + ? window.matchMedia("(prefers-color-scheme: dark)") + : null; + +function resolveTheme(): ThemeMode { + const v = localStorage.getItem(STORAGE_KEY); + if (v === "light" || v === "dark") return v as ThemeMode; + return mql?.matches ? "dark" : "light"; +} + +function applyToDOM(mode: ThemeMode): void { + document.documentElement.setAttribute("data-theme", mode); + if (themeToggleButton) + themeToggleButton.setAttribute( + "aria-pressed", + mode === "dark" ? "true" : "false", + ); + if (themeIcon) { + themeIcon.src = + mode === "dark" + ? "/assets/ui-svgs/dark-mode-sun.svg" + : "/assets/ui-svgs/dark-mode-moon.svg"; + themeIcon.alt = + mode === "dark" ? "Switch to Light Mode" : "Switch to Dark Mode"; + } +} + +export function applyTheme(mode: ThemeMode): void { + localStorage.setItem(STORAGE_KEY, mode); + applyToDOM(mode); +} + +export function loadSavedTheme(): void { + applyToDOM(resolveTheme()); + + if (mql) { + const onSystemChange = (e: MediaQueryListEvent) => { + const hasOverride = + localStorage.getItem(STORAGE_KEY) === "light" || + localStorage.getItem(STORAGE_KEY) === "dark"; + if (!hasOverride) applyToDOM(e.matches ? "dark" : "light"); + }; + if ("addEventListener" in mql) { + mql.addEventListener("change", onSystemChange); + } else if (typeof (mql as any).addListener === "function") { + (mql as any).addListener(onSystemChange); + } + } + + window.addEventListener("storage", (e) => { + if (e.key === STORAGE_KEY) applyToDOM(resolveTheme()); + }); +} + +export function toggleTheme(): void { + const next = resolveTheme() === "dark" ? "light" : "dark"; + localStorage.setItem(STORAGE_KEY, next); + applyToDOM(next); +} +themeToggleButton?.addEventListener("click", toggleTheme); diff --git a/src/ts/time_manager/timeManager.ts b/src/ts/input_manager/timeManager.ts similarity index 98% rename from src/ts/time_manager/timeManager.ts rename to src/ts/input_manager/timeManager.ts index 57fe026..5aa1d49 100644 --- a/src/ts/time_manager/timeManager.ts +++ b/src/ts/input_manager/timeManager.ts @@ -1,5 +1,6 @@ import { setRenderFireworks } from "../renderer/fireworksRenderer"; import { getTotalReplayTicks } from "../replay_loader/replayLoader"; +import { applyTheme } from "./themeManager"; const playButton = document.getElementById( "play-pause-button", @@ -291,6 +292,8 @@ export async function setupTimeManager() { button: speedDownButton, }, f: { action: () => toggleFullscreen(), button: fullscreenToggleButton }, + d: { action: () => applyTheme("dark") }, + l: { action: () => applyTheme("light") }, }; window.addEventListener("keydown", (event) => { diff --git a/src/ts/main.ts b/src/ts/main.ts index 2350e55..14267a7 100644 --- a/src/ts/main.ts +++ b/src/ts/main.ts @@ -1,3 +1,5 @@ +import { loadSavedTheme } from "./input_manager/themeManager.js"; + const svgCanvas = document.getElementById("svg-canvas") as HTMLElement; window.addEventListener("DOMContentLoaded", async () => { @@ -25,7 +27,7 @@ window.addEventListener("DOMContentLoaded", async () => { const { setupReplayLoader } = await import("./replay_loader/replayLoader.js"); const { setupTimeManager, startPlayback, isAtEnd } = await import( - "./time_manager/timeManager.js" + "./input_manager/timeManager.js" ); const { setupRenderer } = await import("./renderer/renderer.js"); @@ -73,4 +75,7 @@ window.addEventListener("DOMContentLoaded", async () => { window.addEventListener("resize", updateSvgSize); window.addEventListener("load", updateSvgSize); updateSvgSize(); + + // theme + loadSavedTheme(); }); diff --git a/src/ts/renderer/objectRenderer.ts b/src/ts/renderer/objectRenderer.ts index 4dbf276..e0dadea 100644 --- a/src/ts/renderer/objectRenderer.ts +++ b/src/ts/renderer/objectRenderer.ts @@ -1,10 +1,10 @@ +import type { tickData } from "../input_manager/timeManager"; import { getBarMetrics, type TickObject } from "../replay_loader/object"; import { getActionsByExecutor, getNameOfUnitType, getStateAt, } from "../replay_loader/replayLoader"; -import type { tickData } from "../time_manager/timeManager"; import { EaseInOutTimingCurve, MidTickIncreaseTimingCurve, @@ -202,7 +202,7 @@ function drawObject( img = document.createElementNS(svgNS, "image"); img.setAttribute("data-obj-id", obj.id.toString()); } - + img.classList.add("game-object"); img.classList.remove("not-touched"); img.classList.remove("team-0", "team-1"); if (obj.type === 0 || obj.type === 1) { diff --git a/src/ts/renderer/renderer.ts b/src/ts/renderer/renderer.ts index 1a3ad00..63dbc29 100644 --- a/src/ts/renderer/renderer.ts +++ b/src/ts/renderer/renderer.ts @@ -1,3 +1,4 @@ +import { getCurrentTickData, isDirty } from "../input_manager/timeManager"; import type { GameConfig } from "../replay_loader/config"; import { formatObjectData, type TickObject } from "../replay_loader/object"; import { @@ -5,7 +6,6 @@ import { getGameMisc, getStateAt, } from "../replay_loader/replayLoader"; -import { getCurrentTickData, isDirty } from "../time_manager/timeManager"; import { calcAndDrawObject, initializeTeamMapping } from "./objectRenderer"; const svgNS = "http://www.w3.org/2000/svg"; @@ -104,7 +104,7 @@ function refreshTooltipFromSVGPoint( if (obj) { tooltipElement.innerHTML = formatObjectData(obj); } else { - tooltipElement.innerHTML = `📍 Position: [${tx}, ${ty}]`; + tooltipElement.innerHTML = `📍 Position: [x: ${tx}, y: ${ty}]`; } } export async function setupRenderer(): Promise { @@ -151,14 +151,11 @@ export async function setupRenderer(): Promise { for (let y = 0; y < gridSize; y++) { for (let x = 0; x < gridSize; x++) { const rect = document.createElementNS(svgNS, "rect"); - rect.setAttribute("class", "persistent"); + rect.setAttribute("class", "grid-cell persistent"); rect.setAttribute("x", x.toString()); rect.setAttribute("y", y.toString()); rect.setAttribute("width", "1"); rect.setAttribute("height", "1"); - rect.setAttribute("fill", "#f7f7f7"); - rect.setAttribute("stroke", "black"); - rect.setAttribute("stroke-width", "0.01"); svgCanvas.appendChild(rect); } } diff --git a/src/ts/replay_loader/object.ts b/src/ts/replay_loader/object.ts index 1897f9d..a612266 100644 --- a/src/ts/replay_loader/object.ts +++ b/src/ts/replay_loader/object.ts @@ -63,13 +63,13 @@ export function formatObjectData(obj: TickObject): string { lines.push({ line: `❓ Object Type: ${objectTypeNames[obj.type] || "Unknown"}`, priority: 4, - color: "black", + color: "var(--text)", }); - lines.push({ line: `#️⃣ ID: ${obj.id}`, priority: 5, color: "black" }); + lines.push({ line: `#️⃣ ID: ${obj.id}`, priority: 5, color: "var(--text)" }); lines.push({ - line: `📍 Position: [${obj.x}, ${obj.y}]`, + line: `📍 Position: [x: ${obj.x}, y: ${obj.y}]`, priority: 6, - color: "black", + color: "var(--text)", }); switch (obj.type) { @@ -77,7 +77,7 @@ export function formatObjectData(obj: TickObject): string { lines.push({ line: `🏁 Team ID: ${obj.teamId}`, priority: 5, - color: "black", + color: "var(--text)", }); lines.push({ line: `💰 Balance: ${obj.balance}`, @@ -89,7 +89,7 @@ export function formatObjectData(obj: TickObject): string { lines.push({ line: `🏁 Team ID: ${obj.teamId}`, priority: 5, - color: "black", + color: "var(--text)", }); lines.push({ line: `💰 Balance: ${obj.balance}`, @@ -114,7 +114,7 @@ export function formatObjectData(obj: TickObject): string { lines.push({ line: `💣 Explosion Countdown: ${obj.countdown}`, priority: -1, - color: "black", + color: "var(--text)", }); break; } diff --git a/src/ts/replay_loader/replayLoader.ts b/src/ts/replay_loader/replayLoader.ts index 31a08da..15b34b6 100644 --- a/src/ts/replay_loader/replayLoader.ts +++ b/src/ts/replay_loader/replayLoader.ts @@ -1,5 +1,5 @@ +import { resetTimeManager } from "../input_manager/timeManager"; import { setupRenderer } from "../renderer/renderer"; -import { resetTimeManager } from "../time_manager/timeManager"; import type { TickAction } from "./action"; import type { GameConfig } from "./config"; import type { TickObject } from "./object";