diff --git a/css/solar.css b/css/solar.css index a49168d..92ec7f5 100644 --- a/css/solar.css +++ b/css/solar.css @@ -1131,6 +1131,114 @@ input[type='range']::-webkit-slider-runnable-track { stroke-width: 2; } +/* --- Strasse ------------------------------------------------------------ + Sichtbar nur waehrend der Fahrt. Sie traegt die eigentliche Bewegung: der + Belag dunkelt die Flaeche ab, die Markierungen laufen in den Randstreifen + neben den Raedern, die Baeume ziehen aussen vorbei. + + Beide Schleifen sind so gebaut, dass sie sich selbst treffen: die Striche + wandern um eine Strich-Lueckenlaenge (26 + 20 = 46), die Baumreihen um + ihren Abstand (160). Nach einem Durchlauf steht das Muster wieder wie + zuvor - deshalb sieht man keinen Sprung. + + Alle drei laufen mit derselben Geschwindigkeit von rund 180 Einheiten je + Sekunde: Markierungen und Baeume gehoeren zur selben Landschaft, und ein + Baum, der langsamer zurueckbleibt als der Strich daneben, faellt sofort + auf. */ +.skoda-auto .strasse { display: none; } +.skoda-auto.faehrt .strasse { display: block; } + +.skoda-auto .strasse .belag { + fill: rgba(8, 10, 12, 0.35); +} + +.skoda-auto .strasse .markierung line { + stroke: rgba(232, 237, 233, 0.35); + stroke-width: 3; + stroke-dasharray: 26 20; + animation: skoda-markierung 0.26s linear infinite; +} + +.skoda-auto .strasse .baum { + fill: rgba(96, 140, 104, 0.55); + stroke: rgba(52, 84, 60, 0.7); + stroke-width: 1.2; +} +.skoda-auto .strasse .baumreihe { animation: skoda-baeume 0.9s linear infinite; } +/* Die rechte Reihe etwas langsamer und mit Vorlauf - sonst stehen sich die + Baeume paarweise gegenueber. */ +.skoda-auto .strasse .rechts { animation-duration: 1.05s; animation-delay: -0.4s; } + +@keyframes skoda-markierung { + from { transform: translateY(0); } + to { transform: translateY(46px); } +} +@keyframes skoda-baeume { + from { transform: translateY(0); } + to { transform: translateY(160px); } +} + +/* --- Fahrtwind ---------------------------------------------------------- + Vier Streifen neben dem Wagen, die von vorn nach hinten laufen. Sichtbar + nur, solange zeichneFahrt() dem SVG die Klasse "faehrt" gibt. + + Die Laenge der Streifen steckt im Markup (y1/y2), die Bewegung hier: jede + Spur laeuft in eigenem Takt und mit eigenem Vorlauf ueber das Bild, sonst + marschieren die vier im Gleichschritt und es sieht nach Zebrastreifen aus + statt nach Fahrt. Der Weg reicht von weit oberhalb bis weit unterhalb der + viewBox (-8 bis 508), damit kein Streifen im Bild entsteht oder endet. */ +.skoda-auto .fahrtwind { display: none; } +.skoda-auto.faehrt .fahrtwind { display: block; } +/* Die Streifen ueber dem Wagen liegen ueber den beiden Knoepfen; sie duerfen + deren Beruehrungen nicht abfangen. */ +.skoda-auto .fahrtwind-oben { pointer-events: none; } + +.skoda-auto .fahrtwind line { + stroke: rgba(var(--skoda-blech), 0.75); + stroke-width: 4; + stroke-linecap: round; + animation: skoda-fahrtwind 1.1s linear infinite; +} +/* Vier Spuren, jede mit eigenem Takt und Vorlauf. Der Wind zieht etwa + anderthalbmal so schnell wie die Landschaft: schneller, weil Luft ueber den + Wagen streicht, aber nicht so viel schneller, dass die beiden Bewegungen + auseinanderfallen. */ +.skoda-auto .fahrtwind .b1 { animation-duration: 2.40s; animation-delay: -0.30s; opacity: .5; } +.skoda-auto .fahrtwind .b6 { animation-duration: 2.60s; animation-delay: -1.70s; opacity: .5; } + +/* Ueber dem Fahrzeug: heller, duenner, durchsichtiger. Der Wind zieht ueber + das Blech hinweg - er soll sich darauf legen, nicht hineinschneiden. Die + Streifen stehen dafuer in einer eigenen Gruppe am Ende des SVG (siehe + dort); ihre geringe Deckung haelt Ladestand und Umrisse lesbar. */ +.skoda-auto .fahrtwind .ueber { + stroke: rgba(232, 237, 233, 0.85); + stroke-width: 3; +} +.skoda-auto .fahrtwind .b7 { animation-duration: 2.30s; animation-delay: -0.60s; opacity: .34; } +.skoda-auto .fahrtwind .b10 { animation-duration: 2.70s; animation-delay: -1.20s; opacity: .34; } + +@keyframes skoda-fahrtwind { + from { transform: translateY(0); } + to { transform: translateY(680px); } +} + +/* Wer Bewegung abbestellt hat, bekommt sie nicht - aber auch keine leere + Stelle: die Streifen stehen dann ruhig neben dem Wagen, und das Abzeichen + "unterwegs" im Kopf der Kachel sagt es ohnehin in Worten. */ +@media (prefers-reduced-motion: reduce) { + .skoda-auto .fahrtwind line { + animation: none; + transform: translateY(250px); + opacity: .45; + } + /* Strasse und Baeume bleiben stehen - zu sehen ist dann eine Standaufnahme + statt einer Fahrt, und das Abzeichen "unterwegs" sagt den Rest. */ + .skoda-auto .strasse .markierung line, + .skoda-auto .strasse .baumreihe { + animation: none; + } +} + .skoda-auto .rad rect { fill: rgba(18, 20, 24, 0.9); } .skoda-auto .spiegel rect { fill: rgba(var(--skoda-blech), 0.55); } .skoda-auto .spoiler { fill: rgba(var(--skoda-blech), 0.55); } diff --git a/js/solar/skodaMQTT.js b/js/solar/skodaMQTT.js index 30d0c80..99be232 100644 --- a/js/solar/skodaMQTT.js +++ b/js/solar/skodaMQTT.js @@ -426,7 +426,16 @@ function liveWerte() { klima: stand ? stand.ac_state : null, // null heißt: das Fahrzeug meldet den Zustand des Schlosses selbst nicht. verriegelt: (stand && stand.locked !== null && stand.locked !== undefined) - ? Number(stand.locked) === 1 : null + ? Number(stand.locked) === 1 : null, + /* + * Fährt gerade. Kommt allein aus der Tabelle - der Broker kennt den + * Parkzustand nicht, unter solarManager/ev* stehen nur Ladestand, + * Reichweite und Ladung. Der Sammler fragt das Fahrzeug unterwegs alle + * vier Minuten, die Seite lädt jede Minute nach: die Anzeige hinkt also + * um wenige Minuten hinterher. Für "rollt gerade" reicht das; ein + * Tachometer ist es nicht. + */ + faehrt: !!(stand && stand.park_state === "IN_MOTION") }; } @@ -538,6 +547,25 @@ function zeichneAbzeichen(w) { } } +/** + * Fahrt anzeigen: Fahrtwind am Fahrzeug, Abzeichen im Kopf der Kachel. + * + * Zwei Wege für dieselbe Aussage, und beide werden gebraucht. Die Streifen + * sieht man aus dem Augenwinkel, ohne zu lesen - dafür sind sie da. Wer die + * Seite vorgelesen bekommt oder Bewegungen abgeschaltet hat, hat von ihnen + * nichts; deshalb steht es zusätzlich als Wort neben Schloss und Ladezustand. + */ +function zeichneFahrt(w) { + const bild = $("skodaAuto"); + if (bild) { + bild.classList.toggle("faehrt", w.faehrt); + } + const abzeichen = $("skodaUnterwegs"); + if (abzeichen) { + abzeichen.hidden = !w.faehrt; + } +} + /** * Herkunft des Ladestroms: was die Anlage im Augenblick liefert, gegen das, * was die Wallbox zieht. Ohne Ladung hat der Balken nichts zu teilen und @@ -570,6 +598,7 @@ function zeichneLive() { zeichneKlimaknopf(w); zeichneKennzahlen(w); zeichneAbzeichen(w); + zeichneFahrt(w); zeichneLadequelle(w); } diff --git a/restricted/skoda.php b/restricted/skoda.php index 09b8478..850e292 100644 --- a/restricted/skoda.php +++ b/restricted/skoda.php @@ -58,6 +58,8 @@