From de994bced961ad50b8a655ca59d6a872a414c410 Mon Sep 17 00:00:00 2001 From: vini Date: Sun, 19 Jul 2026 10:23:16 -0300 Subject: [PATCH] refactor: idle-friendly render loops, drop dead strobe code Rain and globe rAF loops now start on demand and stop when their effect fully fades, instead of ticking every frame forever. Lightning clears the bluish strobe tint after each burst. Removed triggerStrobe, which was disabled and unreferenced. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_015HtPHsTnDcLVSCiF5FGHZj --- plugin/contents/ui/dancer.html | 50 ++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/plugin/contents/ui/dancer.html b/plugin/contents/ui/dancer.html index 53eb3d3..16caced 100644 --- a/plugin/contents/ui/dancer.html +++ b/plugin/contents/ui/dancer.html @@ -1802,7 +1802,15 @@ globeCanvas.style.cssText = 'opacity:0;transition:opacity 1.5s ease;'; sunEl.appendChild(globeCanvas); const gctx = globeCanvas.getContext('2d'); -let globeRot = 0, lastGlobeTs = 0; +let globeRot = 0, lastGlobeTs = 0, globeLoopOn = false; + +/* Loop roda só enquanto o globo é visível — dorme quando baladaAmt zera */ +function startGlobeLoop() { + if (globeLoopOn) return; + globeLoopOn = true; + lastGlobeTs = 0; + requestAnimationFrame(drawGlobe); +} /* 8 luzes nos eixos ortogonais — cobertura 360° garantida. ±Y não são afetados pelo lrot, ±X e ±Z orbitam entre si. */ @@ -1818,6 +1826,7 @@ const MIRROR_LIGHTS = [ ]; function drawGlobe(ts) { + if (!balada && baladaAmt < 0.01) { globeLoopOn = false; lastGlobeTs = 0; return; } requestAnimationFrame(drawGlobe); if (baladaAmt < 0.01) { lastGlobeTs = 0; return; } globeCanvas.style.opacity = chuva ? 0 : baladaAmt; @@ -1900,7 +1909,6 @@ function drawGlobe(ts) { gctx.restore(); } -requestAnimationFrame(drawGlobe); const discoDots = document.getElementById('discoDots'); const strobeEl = document.getElementById('strobe'); @@ -1959,22 +1967,6 @@ setInterval(() => { if (baladaAmt > 0.3 && discoDots.childElementCount < 28) spawnDiscoDot(); }, 280); -/* ── Strobe no beat ── */ -let strobeCooldown = false; -function triggerStrobe() { - if (!balada || strobeCooldown) return; - strobeCooldown = true; - strobeEl.style.transition = 'none'; - strobeEl.style.opacity = '0.2'; - setTimeout(() => { - strobeEl.style.transition = 'opacity 0.3s ease'; - strobeEl.style.opacity = '0'; - setTimeout(() => { strobeCooldown = false; }, 600); - }, 50); -} -/* strobe desativado — muito agressivo visualmente */ -/* setInterval(() => { if (balada && Math.random() < 0.35) triggerStrobe(); }, BEAT_MS * 2); */ - /* ── Pulso do sol/disco no beat ── */ function globeBeat() { if (!balada || !sunEl) return; @@ -1989,7 +1981,7 @@ setInterval(() => { if (balada) globeBeat(); }, BEAT_MS); function setBaladaMode(on) { if (on === balada) return; balada = on; - if (on) setChuvaMode(false); + if (on) { setChuvaMode(false); startGlobeLoop(); } document.body.classList.toggle('balada', balada); /* opacidade do globo é controlada por drawGlobe via baladaAmt */ } @@ -2066,16 +2058,26 @@ function initRain() { } } -let lastRainTs = 0; +let lastRainTs = 0; +let rainLoopOn = false; + +/* Loop roda só enquanto há chuva visível — dorme quando chuvaAmt zera */ +function startRainLoop() { + if (rainLoopOn) return; + rainLoopOn = true; + lastRainTs = 0; + requestAnimationFrame(drawRain); +} function drawRain(ts) { - requestAnimationFrame(drawRain); const dt = lastRainTs ? Math.min((ts - lastRainTs) / 1000, 0.05) : 0; lastRainTs = ts; chuvaAmt += ((chuva ? 1 : 0) - chuvaAmt) * Math.min(1, dt * 0.5); const W = rainCanvas.width, H = rainCanvas.height; rctx.clearRect(0, 0, W, H); + if (!chuva && chuvaAmt < 0.005) { rainLoopOn = false; return; } + requestAnimationFrame(drawRain); if (chuvaAmt < 0.005) return; rainDrops.forEach(d => { @@ -2112,6 +2114,8 @@ function triggerLightning() { }, delay); delay += 100 + (Math.random() * 110 | 0); } + /* limpa o tom azulado do strobe depois da rajada */ + setTimeout(() => { strobeEl.style.background = ''; }, delay + 300); } (function scheduleLightning() { @@ -2123,7 +2127,7 @@ function triggerLightning() { function setChuvaMode(on) { if (on === chuva) return; chuva = on; - if (on) setBaladaMode(false); + if (on) { setBaladaMode(false); startRainLoop(); } document.body.classList.toggle('chuva', chuva); if (on) { fogWisps.forEach(w => { @@ -2156,7 +2160,7 @@ let chuvaFileVal = null; if (window.innerWidth > 0 && window.innerHeight > 0) { resizeRain(); initRain(); - requestAnimationFrame(drawRain); + if (chuva) startRainLoop(); } else { setTimeout(initRainOnLoad, 80); }