init: Elden Ring death counter with multi-client server
Deno HTTP + WebSocket server serving three pages: - / desktop with YOU DIED overlay and keyboard controls - /mobile touch-optimized control page - /obs transparent browser source for OBS Count persisted to counter.json, synced in real time across all connected clients. Compiles to a self-contained Windows .exe via deno compile.
This commit is contained in:
121
obs.html
Normal file
121
obs.html
Normal file
@@ -0,0 +1,121 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Elden Counter – OBS</title>
|
||||
|
||||
<style>
|
||||
:root{
|
||||
--border: rgba(212, 175, 55, .30);
|
||||
--text: rgba(245, 238, 210, .92);
|
||||
--muted: rgba(245, 238, 210, .62);
|
||||
}
|
||||
|
||||
*{ box-sizing:border-box; }
|
||||
|
||||
html, body{
|
||||
margin:0;
|
||||
padding:0;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
body{
|
||||
display:inline-flex;
|
||||
font-family: ui-serif, Georgia, "Times New Roman", Times, serif;
|
||||
}
|
||||
|
||||
.bigBox{
|
||||
border:1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
padding: 26px 32px 22px;
|
||||
display:grid;
|
||||
place-items:center;
|
||||
/* Fixed size so layout never jumps as numbers grow */
|
||||
width: 440px;
|
||||
height: 160px;
|
||||
background:
|
||||
radial-gradient(500px 220px at 50% 30%, rgba(212,175,55,.12), transparent 70%),
|
||||
linear-gradient(180deg, rgba(255,255,255,.04), rgba(0,0,0,.12));
|
||||
box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
|
||||
}
|
||||
|
||||
.roman{
|
||||
font-size: 72px;
|
||||
font-weight: 900;
|
||||
letter-spacing: 4px;
|
||||
color: rgba(245,238,210,.94);
|
||||
text-shadow:
|
||||
0 0 16px rgba(212,175,55,.12),
|
||||
0 0 34px rgba(212,175,55,.08);
|
||||
text-align:center;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.arabic{
|
||||
margin-top:8px;
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
letter-spacing:.2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section class="bigBox" aria-live="polite">
|
||||
<div class="roman" id="roman">—</div>
|
||||
<div class="arabic" id="arabic">Tode: 0</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
function toRoman(n) {
|
||||
const map = [
|
||||
{ val: 1000, sym: "M" },
|
||||
{ val: 900, sym: "CM" },
|
||||
{ val: 500, sym: "D" },
|
||||
{ val: 400, sym: "CD" },
|
||||
{ val: 100, sym: "C" },
|
||||
{ val: 90, sym: "XC" },
|
||||
{ val: 50, sym: "L" },
|
||||
{ val: 40, sym: "XL" },
|
||||
{ val: 10, sym: "X" },
|
||||
{ val: 9, sym: "IX" },
|
||||
{ val: 5, sym: "V" },
|
||||
{ val: 4, sym: "IV" },
|
||||
{ val: 1, sym: "I" }
|
||||
];
|
||||
let res = "";
|
||||
for (const { val, sym } of map) {
|
||||
while (n >= val) { res += sym; n -= val; }
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const romanEl = document.getElementById("roman");
|
||||
const arabicEl = document.getElementById("arabic");
|
||||
|
||||
function clamp(n, min, max){ return Math.max(min, Math.min(max, n)); }
|
||||
|
||||
function render(count) {
|
||||
const n = clamp(count, 0, 3999);
|
||||
romanEl.textContent = n === 0 ? "—" : toRoman(n);
|
||||
arabicEl.textContent = `Tode: ${n}`;
|
||||
}
|
||||
|
||||
let ws;
|
||||
|
||||
function connect() {
|
||||
ws = new WebSocket(`ws://${location.host}/ws`);
|
||||
ws.onmessage = (e) => {
|
||||
const msg = JSON.parse(e.data);
|
||||
if (typeof msg.count === "number") render(msg.count);
|
||||
};
|
||||
ws.onclose = () => setTimeout(connect, 2000);
|
||||
ws.onerror = () => ws.close();
|
||||
}
|
||||
|
||||
connect();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user