diff --git a/css/solar.css b/css/solar.css index 0ed35e1..d31b0bf 100644 --- a/css/solar.css +++ b/css/solar.css @@ -1165,6 +1165,53 @@ input[type='range']::-webkit-slider-runnable-track { to { transform: translateY(472.5px); } } +/* --- Bananenschale ------------------------------------------------------ + Der Ostergruss. Ausgeloest wird er selten und nur waehrend der Fahrt (siehe + bananeVielleicht() in js/solar/skodaMQTT.js); hier steht, wie er aussieht. + + Zwei Bewegungen greifen ineinander: die Schale laeuft mit der Strasse mit, + und wenn sie unter der Vorderachse ist, kommt der Wagen ins Schleudern. Der + Vorlauf der zweiten Bewegung ist deshalb kein Gefuehl, sondern gerechnet: + die Schale startet 40 Einheiten ueber dem Bild, die Vorderachse liegt bei + 97, macht 137 Einheiten - bei 437 Einheiten je Sekunde sind das 0,31 s. + + Der Wagen dreht sich um seinen Schwerpunkt, nicht um die Bildmitte; ohne + transform-box: view-box bezoege sich transform-origin auf den Rahmen der + Gruppe und der Bogen saehe falsch aus. */ +.skoda-auto .bananenschale { display: none; } +.skoda-auto.banane .bananenschale { + display: block; + animation: skoda-schale 1.5s linear; +} +.skoda-auto .bananenschale use { + fill: #e8c74a; + stroke: rgba(120, 92, 12, 0.75); + stroke-width: 0.8; +} +.skoda-auto .bananenschale .strunk { fill: #b8912c; } + +.skoda-auto.banane #wagen { + transform-box: view-box; + transform-origin: 112px 250px; + animation: skoda-schleudern 1.2s 0.31s ease-in-out; +} + +@keyframes skoda-schale { + from { transform: translateY(-40px); } + to { transform: translateY(560px); } +} + +/* Erst ein Ausbrechen nach rechts, dann das Gegenlenken, dann austrudeln - + in dieser Reihenfolge faengt sich ein Fahrzeug wieder. */ +@keyframes skoda-schleudern { + 0% { transform: rotate(0deg) translateX(0); } + 18% { transform: rotate(4.5deg) translateX(5px); } + 45% { transform: rotate(-3.5deg) translateX(-4px); } + 70% { transform: rotate(1.8deg) translateX(2px); } + 88% { transform: rotate(-0.7deg) translateX(-1px); } + 100% { transform: rotate(0deg) translateX(0); } +} + /* --- Fahrtwind ---------------------------------------------------------- Vier Streifen neben dem Wagen, die von vorn nach hinten laufen. Sichtbar nur, solange zeichneFahrt() dem SVG die Klasse "faehrt" gibt. @@ -1222,6 +1269,14 @@ input[type='range']::-webkit-slider-runnable-track { .skoda-auto .strasse .leitlinie { animation: none; } + /* Der Ostergruss faellt ganz aus: ein schleuderndes Fahrzeug ist genau die + Art Bewegung, die abbestellt wurde. Ausgeloest wird er hier gar nicht + erst - das prueft das Skript zusaetzlich. */ + .skoda-auto.banane .bananenschale, + .skoda-auto.banane #wagen { + animation: none; + } + .skoda-auto.banane .bananenschale { display: none; } } .skoda-auto .rad rect { fill: rgba(18, 20, 24, 0.9); } diff --git a/js/solar/skodaMQTT.js b/js/solar/skodaMQTT.js index 99be232..e73ef5b 100644 --- a/js/solar/skodaMQTT.js +++ b/js/solar/skodaMQTT.js @@ -547,6 +547,35 @@ function zeichneAbzeichen(w) { } } +/* ------------------------------------------------------------ Ostergruß */ + +/* + * Ganz selten liegt eine Bananenschale auf der Fahrbahn. + * + * Geprüft wird alle 20 Sekunden, und nur während der Fahrt; die Chance liegt + * bei zwei Prozent. Das ist im Mittel einmal in gut sechzehn Minuten Fahrt - + * selten genug, dass man es kaum erwartet, und häufig genug, dass es + * irgendwann jemand sieht. + * + * Der Auftritt dauert anderthalb Sekunden, danach fällt die Klasse wieder ab. + * Wer Bewegungen abbestellt hat, bekommt ihn gar nicht erst - ein + * schleuderndes Auto ist genau das, was damit gemeint ist. + */ +const BANANE_TAKT = 20000; +const BANANE_CHANCE = 0.02; +const BANANE_DAUER = 1600; + +function bananeVielleicht() { + const bild = $("skodaAuto"); + if (!bild || !bild.classList.contains("faehrt")) return; + if (bild.classList.contains("banane")) return; // läuft schon + if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; + if (Math.random() >= BANANE_CHANCE) return; + + bild.classList.add("banane"); + setTimeout(function () { bild.classList.remove("banane"); }, BANANE_DAUER); +} + /** * Fahrt anzeigen: Fahrtwind am Fahrzeug, Abzeichen im Kopf der Kachel. * @@ -559,6 +588,9 @@ function zeichneFahrt(w) { const bild = $("skodaAuto"); if (bild) { bild.classList.toggle("faehrt", w.faehrt); + // Hält der Wagen mitten im Schleudern an, bleibt sonst eine Schale auf + // der Fahrbahn liegen, die niemand mehr überfährt. + if (!w.faehrt) bild.classList.remove("banane"); } const abzeichen = $("skodaUnterwegs"); if (abzeichen) { @@ -1496,6 +1528,7 @@ document.addEventListener("readystatechange", function () { ladeLadungen(); ladeKurve(); ladeFahrten(); ladeStrecke(); }, 300000); setInterval(ladeGesundheit, 900000); + setInterval(bananeVielleicht, BANANE_TAKT); // Leaflet rechnet die Kachelanordnung selbst neu, sobald es erfährt, dass // sein Container eine andere Größe hat. diff --git a/restricted/skoda.php b/restricted/skoda.php index 351a2e4..9df30e0 100644 --- a/restricted/skoda.php +++ b/restricted/skoda.php @@ -108,6 +108,14 @@ 120 Grad versetzt ein. --> + + + + + + + @@ -423,6 +453,8 @@ Klima und Lüftung steuern + +