diff --git a/static/animation.js b/static/animation.js index d1b877c..219db29 100644 --- a/static/animation.js +++ b/static/animation.js @@ -19,6 +19,7 @@ let opacity = null; // Float32Array ROWS*COLS — current fade value [0,1 let animFrame = null; let lastStepTime = 0; let lastFrameTime = 0; +let initDateStr = ''; // date string when animation was last initialized // ── Board helpers ────────────────────────────────────────────────────────── @@ -91,6 +92,36 @@ function loadFromCookie() { catch { return null; } } +// ── Lightning strike ─────────────────────────────────────────────────────── + +function maybeLightningStrike() { + if (Math.random() >= 0.001) return; + const r = Math.floor(Math.random() * ROWS); + const c = Math.floor(Math.random() * COLS); + const s = 4 + Math.floor(Math.random() * 7); // 4–10 inclusive + for (let dr = 0; dr < s; dr++) { + for (let dc = 0; dc < s; dc++) { + board[idx((r + dr) % ROWS, (c + dc) % COLS)] = Math.random() < 0.5 ? 1 : 0; + } + } +} + +// ── Midnight rollover ────────────────────────────────────────────────────── + +function todayStr() { + const d = new Date(); + return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`; +} + +function checkDateRollover() { + if (todayStr() === initDateStr) return; + // New day — reinitialize with a fresh random board + initDateStr = todayStr(); + board = randomBoard(); + opacity = new Float32Array(ROWS * COLS); // all zeros → cells fade in + saveToCookie(); +} + // ── Setup ────────────────────────────────────────────────────────────────── function measureCmPx() { @@ -115,6 +146,7 @@ function setup() { resize(); window.addEventListener('resize', resize); + initDateStr = todayStr(); board = loadFromCookie() || randomBoard(); opacity = new Float32Array(ROWS * COLS); // Initialise opacity to match loaded state (no fade-in on first load) @@ -123,6 +155,10 @@ function setup() { lastStepTime = performance.now(); lastFrameTime = performance.now(); animFrame = requestAnimationFrame(frame); + + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible') checkDateRollover(); + }); } function resize() { @@ -137,6 +173,8 @@ function frame(ts) { lastFrameTime = ts; if (ts - lastStepTime >= STEP_MS) { + checkDateRollover(); + maybeLightningStrike(); board = stepConway(board); lastStepTime = ts; }