From 6246e17f67c354cece99ce80ec5b12a6af583b45 Mon Sep 17 00:00:00 2001 From: sHa Date: Sun, 22 Feb 2026 00:31:41 +0200 Subject: [PATCH] feat: track total hits for logo letters and update related logic --- src/js/logoController.js | 18 ++++++++++++++---- src/js/logoLetter.js | 7 ++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/js/logoController.js b/src/js/logoController.js index a51af30..2d521b2 100644 --- a/src/js/logoController.js +++ b/src/js/logoController.js @@ -262,7 +262,8 @@ export class LogoController { * @returns {number[]} */ getHitCounts() { - return this.#letters.map(l => l.bumpCount); + // return totalHits so previously stored values persist as totals + return this.#letters.map(l => l.totalHits); } /** @@ -273,9 +274,12 @@ export class LogoController { setHitCounts(counts) { if (!Array.isArray(counts)) return; for (let i = 0; i < this.#letters.length; i++) { - this.#letters[i].bumpCount = counts[i] ?? 0; + const val = counts[i] ?? 0; + this.#letters[i].totalHits = val; + // keep bumpCount at least the same so ejection logic doesn't fire + this.#letters[i].bumpCount = Math.min(this.#letters[i].bumpCount, val); if (this.#letters[i].debugEl) { - this.#letters[i].debugEl.textContent = String(this.#letters[i].bumpCount); + this.#letters[i].debugEl.textContent = String(val); } } } @@ -286,6 +290,7 @@ export class LogoController { resetCounters() { for (const letter of this.#letters) { letter.bumpCount = 0; + letter.totalHits = 0; if (letter.debugEl) letter.debugEl.textContent = '0'; // remove any red proximity colouring so letters appear white again if (typeof letter._resetProximityColor === 'function') { @@ -327,9 +332,10 @@ export class LogoController { slotIndex: i, // no bumpThreshold argument -> constructor uses DEFAULTS range }); - // restore bumpCount/ejected/position if present + // restore bumpCount/totalHits/ejected/position if present if (saved) { letter.bumpCount = saved.bumpCount ?? 0; + letter.totalHits = saved.totalHits ?? 0; letter.ejected = saved.ejected ?? false; } return letter; @@ -357,8 +363,12 @@ export class LogoController { const saved = savedLetterStates?.[i]; if (saved) { letter.bumpCount = saved.bumpCount ?? 0; + letter.totalHits = saved.totalHits ?? 0; letter.ejected = saved.ejected ?? false; + // display restored total on debug label if visible + if (letter.debugEl) letter.debugEl.textContent = String(letter.totalHits); + // reflect proximity colour based on the restored bump count if (typeof letter._updateProximityColor === 'function') { letter._updateProximityColor(); diff --git a/src/js/logoLetter.js b/src/js/logoLetter.js index b7828c2..5eec8e9 100644 --- a/src/js/logoLetter.js +++ b/src/js/logoLetter.js @@ -33,6 +33,8 @@ export class LogoLetter { // ── Ejection state ─────────────────────────────────────── /** @type {boolean} */ ejected = false; /** @type {number} */ bumpCount = 0; + /** Total hits witnessed by this letter (never decremented). */ + /** @type {number} */ totalHits = 0; /** @type {number} */ bumpThreshold; // ── DOM ─────────────────────────────────────────────────── @@ -183,7 +185,8 @@ export class LogoLetter { */ onBump() { this.bumpCount++; - if (this.debugEl) this.debugEl.textContent = String(this.bumpCount); + this.totalHits++; + if (this.debugEl) this.debugEl.textContent = String(this.totalHits); // colour the letter based on how close it is to the threshold; we only // start showing red when there are 10 or fewer hits remaining, interpolating @@ -236,6 +239,8 @@ export class LogoLetter { */ setDebugVisible(visible) { this.el?.classList.toggle('logo-letter--show-debug', visible); + // when toggling on, ensure debug text reflects totalHits + if (visible && this.debugEl) this.debugEl.textContent = String(this.totalHits); } /**