From 82acc2d1491af8f6c80fc4c574aba43c2c0ba97e Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 27 Jun 2026 10:32:47 +0200 Subject: [PATCH] Scale fire flames with SVG transform anchored at base, floor at 1200W Replace clip-rect height manipulation with translate-scale-translate SVG transform on fire-group, pivoting at the fixed base coordinate y=248. Eliminates base-hopping caused by fill-box bounding-box drift from individual flame flicker animations. Clip rect is now static (guards against flicker overshoot above the pot bottom). Minimum visible flame size floored at the scale corresponding to 1200W. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01JLR2133M2PyjiYq584i2G7 --- web/app.js | 18 ++++++------------ web/index.html | 2 +- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/web/app.js b/web/app.js index dd33efd..50c12e5 100644 --- a/web/app.js +++ b/web/app.js @@ -295,23 +295,17 @@ function updateStirrerVisualization() { // --- Fire visualization --- function updateFireVisualization() { - const g = document.getElementById('fire-group'); - const clipRect = document.getElementById('fire-clip-rect'); + const g = document.getElementById('fire-group'); if (!g) return; - const fireBase = 248; // y of flame base (all paths end here) - const fireTip = 177; // y of tallest flame tip - const fireH = fireBase - fireTip; // 71px total flame height if (heaterPowerSoll <= 0) { g.style.opacity = '0'; - clipRect.setAttribute('height', '0'); + g.removeAttribute('transform'); } else { const intensity = Math.min(1, heaterPowerSoll / heaterMaxPower); - // Always show the lower 35% (base), scale upper 65% with intensity - const visibleH = (0.35 + 0.65 * intensity) * fireH; - const topBuffer = 20; // headroom for flicker scaleY overshoot (~12% of height) - clipRect.setAttribute('y', (fireBase - visibleH - topBuffer).toFixed(1)); - clipRect.setAttribute('height', (visibleH + topBuffer + 2).toFixed(1)); - g.style.opacity = String((0.6 + 0.4 * intensity).toFixed(2)); + const minScale = 1200 / heaterMaxPower; + const scale = Math.max(minScale, intensity); + g.style.opacity = '1'; + g.setAttribute('transform', `translate(0,248) scale(1,${scale.toFixed(3)}) translate(0,-248)`); } } diff --git a/web/index.html b/web/index.html index e9ece89..44f698f 100644 --- a/web/index.html +++ b/web/index.html @@ -59,7 +59,7 @@ - +