From 186cd49649f1b37585e3214920da14497fc3af3f Mon Sep 17 00:00:00 2001 From: NotSoToothless <67082114+FURRO404@users.noreply.github.com> Date: Sun, 14 Jun 2026 22:47:37 -0700 Subject: [PATCH] update canvas winning team glow effect (#1326) --- web/public/js/replay-canvas.js | 21 ++++++--------------- web/views/game-detail.ejs | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/web/public/js/replay-canvas.js b/web/public/js/replay-canvas.js index fbbdcc6..3438bd7 100644 --- a/web/public/js/replay-canvas.js +++ b/web/public/js/replay-canvas.js @@ -736,32 +736,21 @@ class ReplayCanvas { } // ── Tickets meter ────────────────────────────────────────────────────── - _teamSlotName(slot) { - return (this._teamNames && this._teamNames[String(slot)]) - || (slot === this._winnerSlot ? 'Winner' : 'Loser'); - } - _buildTicketsBar(center) { if (!this._tickets) return; const winSlot = this._winnerSlot || 1; - const loseSlot = winSlot === 1 ? 2 : 1; this._tkWinSlot = winSlot; - this._tkLoseSlot = loseSlot; + this._tkLoseSlot = winSlot === 1 ? 2 : 1; const bar = document.createElement('div'); bar.className = 'rc-tickets'; + // No team names here — the win/lose team sections flank the bar already. bar.innerHTML = ` -
- ${this._esc(this._teamSlotName(winSlot))} - 0 -
+ 0
-
- 0 - ${this._esc(this._teamSlotName(loseSlot))} -
`; + 0`; center.appendChild(bar); this.ticketsBar = bar; this._tkWinFill = bar.querySelector('.rc-tk-fill-win'); @@ -780,6 +769,8 @@ class ReplayCanvas { this._tkLoseFill.style.width = (100 - wPct).toFixed(1) + '%'; this._tkWinVal.textContent = w; this._tkLoseVal.textContent = l; + // Game over (loser bled out) → glow the winning side. + this.ticketsBar.classList.toggle('rc-tk-finished', l <= 0); } async _loadEntityIcons() { diff --git a/web/views/game-detail.ejs b/web/views/game-detail.ejs index 50a0850..a7fb236 100644 --- a/web/views/game-detail.ejs +++ b/web/views/game-detail.ejs @@ -505,17 +505,24 @@ font-size: 0.7rem; color: rgba(255,255,255,0.8); } - .rc-tk-side { display: flex; align-items: center; gap: 0.35rem; flex: 0 0 auto; min-width: 0; } - .rc-tk-lose { justify-content: flex-end; } - .rc-tk-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 8rem; } - .rc-tk-win .rc-tk-name { color: #5cdf5c; } - .rc-tk-lose .rc-tk-name { color: #e85555; } - .rc-tk-val { font-variant-numeric: tabular-nums; opacity: 0.85; min-width: 2.6rem; } - .rc-tk-win .rc-tk-val { text-align: right; } + .rc-tk-val { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 2.6rem; } + .rc-tk-val-win { color: #5cdf5c; text-align: right; } + .rc-tk-val-lose { color: #e85555; text-align: left; } .rc-tk-track { flex: 1 1 auto; display: flex; height: 10px; border-radius: 5px; overflow: hidden; background: rgba(255,255,255,0.08); } .rc-tk-fill { height: 100%; transition: width 0.1s linear; } .rc-tk-fill-win { background: #2a8f2a; } .rc-tk-fill-lose { background: #b22020; } + /* Winner glow once the loser has bled out (game over) */ + .rc-tickets.rc-tk-finished .rc-tk-track { animation: rcTkGlow 1.2s ease-in-out infinite; } + .rc-tickets.rc-tk-finished .rc-tk-val-win { animation: rcTkTextGlow 1.2s ease-in-out infinite; } + @keyframes rcTkGlow { + 0%, 100% { box-shadow: 0 0 4px 0 rgba(92,223,92,0.5); } + 50% { box-shadow: 0 0 13px 3px rgba(92,223,92,0.95); } + } + @keyframes rcTkTextGlow { + 0%, 100% { text-shadow: 0 0 4px rgba(92,223,92,0.45); } + 50% { text-shadow: 0 0 11px rgba(92,223,92,0.95); } + } .rc-controls { display: flex; align-items: center;