Fix fire scaling: clip upper flames, keep base constant
Replace scaleY group transform with a dynamic clipPath that reveals flame height proportional to heater power. Base at y=256 stays fixed; only the tips grow with intensity. Includes flicker overshoot buffer. Fire paths shifted +8px down, viewBox extended to 265. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DGKe8JzTM2Gr1fdx9wYXTi
This commit is contained in:
+11
-3
@@ -291,14 +291,22 @@ function updateStirrerVisualization() {
|
||||
// --- Fire visualization ---
|
||||
|
||||
function updateFireVisualization() {
|
||||
const g = document.getElementById('fire-group');
|
||||
const g = document.getElementById('fire-group');
|
||||
const clipRect = document.getElementById('fire-clip-rect');
|
||||
if (!g) return;
|
||||
const fireBase = 256; // y of flame base (all paths end here)
|
||||
const fireTip = 185; // y of tallest flame tip
|
||||
const fireH = fireBase - fireTip; // 71px total flame height
|
||||
if (heaterPowerIst <= 0) {
|
||||
g.style.opacity = '0';
|
||||
g.style.transform = 'scaleY(0.3)';
|
||||
clipRect.setAttribute('height', '0');
|
||||
} else {
|
||||
const intensity = Math.min(1, heaterPowerIst / heaterMaxPower);
|
||||
g.style.transform = `scaleY(${(0.45 + 0.55 * intensity).toFixed(2)})`;
|
||||
// Always show the lower 35% (base), scale upper 65% with intensity
|
||||
const visibleH = (0.35 + 0.65 * intensity) * fireH;
|
||||
const topBuffer = 10; // headroom for flicker scaleY overshoot
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
<div id="pot-view">
|
||||
<svg id="pot-svg" viewBox="0 0 290 255" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg id="pot-svg" viewBox="0 0 290 265" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<clipPath id="pot-clip">
|
||||
<rect x="63" y="30" width="114" height="142"/>
|
||||
@@ -58,6 +58,9 @@
|
||||
<clipPath id="water-clip">
|
||||
<rect id="water-clip-rect" x="63" y="172" width="114" height="0"/>
|
||||
</clipPath>
|
||||
<clipPath id="fire-clip">
|
||||
<rect id="fire-clip-rect" x="60" y="256" width="130" height="0"/>
|
||||
</clipPath>
|
||||
<!-- Flame gradients: solid at base (y=1), transparent at tip (y=0) -->
|
||||
<linearGradient id="fg-red" x1="0" y1="1" x2="0" y2="0">
|
||||
<stop offset="0%" stop-color="#ff2200" stop-opacity="0.95"/>
|
||||
@@ -74,18 +77,18 @@
|
||||
</defs>
|
||||
|
||||
<!-- Fire (shown when heater is on, JS controls scale+opacity) -->
|
||||
<g id="fire-group">
|
||||
<g id="fire-group" clip-path="url(#fire-clip)">
|
||||
<!-- Outer red flame -->
|
||||
<path id="flame-outer" class="flame"
|
||||
d="M76,248 C79,215 92,192 101,208 C106,192 113,177 120,180 C127,177 134,192 139,208 C148,192 161,215 164,248 Z"
|
||||
d="M76,256 C79,223 92,200 101,216 C106,200 113,185 120,188 C127,185 134,200 139,216 C148,200 161,223 164,256 Z"
|
||||
fill="url(#fg-red)"/>
|
||||
<!-- Middle orange flame -->
|
||||
<path id="flame-mid" class="flame"
|
||||
d="M88,248 C91,222 101,204 109,217 C113,204 118,191 122,195 C126,191 131,204 135,217 C143,204 153,222 156,248 Z"
|
||||
d="M88,256 C91,230 101,212 109,225 C113,212 118,199 122,203 C126,199 131,212 135,225 C143,212 153,230 156,256 Z"
|
||||
fill="url(#fg-orange)"/>
|
||||
<!-- Inner yellow flame -->
|
||||
<path id="flame-inner" class="flame"
|
||||
d="M100,248 C102,230 110,215 116,224 C118,215 121,205 124,208 C127,205 130,215 132,224 C138,215 147,230 148,248 Z"
|
||||
d="M100,256 C102,238 110,223 116,232 C118,223 121,213 124,216 C127,213 130,223 132,232 C138,223 147,238 148,256 Z"
|
||||
fill="url(#fg-yellow)"/>
|
||||
</g>
|
||||
|
||||
|
||||
@@ -206,8 +206,6 @@ header#connection-bar {
|
||||
#flame-inner { animation: flicker-3 0.45s ease-in-out infinite 0.15s; }
|
||||
|
||||
#fire-group {
|
||||
transform-box: fill-box;
|
||||
transform-origin: 50% 100%;
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user