diff --git a/css/solar.css b/css/solar.css index 95f9a25..86eca54 100644 --- a/css/solar.css +++ b/css/solar.css @@ -3548,7 +3548,8 @@ svg.enf.enf-hoch { max-height: none; } stroke-dasharray: 0 20; /* Stufen statt stetig: stroke-dashoffset laeuft nicht auf dem Compositor, jede Stufe ist ein Neuzeichnen. 20 je Abschnitt sehen fluessig aus. */ - animation: enf-fliessen var(--dauer, 1.5s) steps(20) infinite; + /* Dauer fest 1 s; das Tempo je Fluss setzt energiefluss.js über playbackRate. */ + animation: enf-fliessen 1s steps(20) infinite; transition: stroke-width .8s, opacity .6s; } .enf .enf-strom { stroke-width: calc(var(--breite, 0) * 1px); } @@ -3944,7 +3945,7 @@ body.anzeige-ohne-maus * { cursor: none !important; } .anzeige-ruhig .enf .enf-bett, .anzeige-ruhig .spk .spk-verlauf.neu .spk-linie { stroke-dashoffset: 0; } .anzeige-ruhig .enf .enf-strom-hof { display: none; } -.anzeige-ruhig .enf .enf-strom { animation: enf-fliessen var(--dauer, 1.5s) steps(8) infinite !important; } +.anzeige-ruhig .enf .enf-strom { animation: enf-fliessen 1s steps(8) infinite !important; } .anzeige-ruhig .enf .enf-rueck .enf-strom { animation-direction: reverse !important; } .anzeige-ruhig .enf .enf-still .enf-strom, .anzeige-ruhig .enf.enf-pause .enf-strom { animation: none !important; } diff --git a/js/solar/energiefluss.js b/js/solar/energiefluss.js index e07dfc1..2f4a560 100644 --- a/js/solar/energiefluss.js +++ b/js/solar/energiefluss.js @@ -334,11 +334,15 @@ el("clipPath", { id: id + "-innen" }, el("defs", null, koerper)) .appendChild(el("circle", { r: r - 11 })); const clip = el("g", { "clip-path": `url(#${id}-innen)` }, koerper); - fuellung = el("g", { class: "enf-fuellung", style: `--stand:0;--r:${r - 11}` }, clip); - const b = r * 4; + // Die Welle ist in Bögen der Breite ri gezeichnet, eine Periode sind + // zwei davon. Die CSS-Animation schiebt um genau 2 * --r - stimmen + // beide nicht überein, springt die Welle am Ende jeder Runde. + const ri = r - 11; + fuellung = el("g", { class: "enf-fuellung", style: `--stand:0;--r:${ri}` }, clip); + const b = ri * 4; el("path", { class: "enf-welle", - d: `M${-b} 0 q${r / 2} -9 ${r} 0 t${r} 0 t${r} 0 t${r} 0 t${r} 0 t${r} 0 t${r} 0 t${r} 0 V${r * 2} H${-b} Z`, + d: `M${-b} 0 q${ri / 2} -9 ${ri} 0` + ` t${ri} 0`.repeat(7) + ` V${ri * 2} H${-b} Z`, }, fuellung); } @@ -548,14 +552,29 @@ const still = a < 15; const breite = still ? 0 : 3.5 + 6.5 * (1 - Math.exp(-a / 3000)); // Schneller bei mehr Leistung: 2,6 s je Abschnitt bei wenig, 0,7 s bei viel. - const dauer = still ? 0 : 0.7 + 1.9 * Math.exp(-a / 3000); - const sig = still ? "still" : breite.toFixed(1) + "|" + dauer.toFixed(2) + "|" + (w < 0); - if (f._sig === sig) return; - f._sig = sig; - f.g.classList.toggle("enf-still", still); - f.g.classList.toggle("enf-rueck", w < 0); - f.g.style.setProperty("--breite", breite.toFixed(1)); - f.g.style.setProperty("--dauer", dauer.toFixed(2) + "s"); + // Gesetzt wird nicht die Dauer der CSS-Animation - eine neue Dauer + // rechnet die Position neu, und die Punkte springen -, sondern ihre + // Abspielgeschwindigkeit; die behält die Position. + const tempo = still ? 1 : 1 / (0.7 + 1.9 * Math.exp(-a / 3000)); + const sig = still ? "still" : breite.toFixed(1) + "|" + (w < 0); + if (f._sig !== sig) { + f._sig = sig; + f.g.classList.toggle("enf-still", still); + f.g.classList.toggle("enf-rueck", w < 0); + f.g.style.setProperty("--breite", breite.toFixed(1)); + } + if (still) return; + // Nach dem Wechsel aus "still" entsteht die Animation erst beim nächsten + // Stilabgleich - deshalb im nächsten Bild. + requestAnimationFrame(() => { + for (const pfad of [f.strom, f.hof]) { + for (const anim of pfad.getAnimations()) { + if (Math.abs(anim.playbackRate - tempo) < 0.02) continue; + if (anim.updatePlaybackRate) anim.updatePlaybackRate(tempo); + else anim.playbackRate = tempo; + } + } + }); } pausieren() {