Ostergruss: eine Bananenschale auf der Fahrbahn
Ganz selten liegt waehrend der Fahrt eine Bananenschale auf der Strasse, und der Wagen kommt kurz ins Schleudern - erst bricht er nach rechts aus, dann faengt ihn das Gegenlenken, dann trudelt er aus. Der Vorlauf der zweiten Bewegung ist gerechnet, nicht geschaetzt: 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. Genau dann setzt das Schleudern ein. Damit das Fahrzeug sich drehen kann, ohne die Strasse mitzunehmen, liegt es jetzt in einer eigenen Gruppe (#wagen); die Schale sitzt im Markup davor und verschwindet unter der Karosserie, sobald der Wagen darueberrollt. Ausgeloest wird alle 20 Sekunden mit zwei Prozent Wahrscheinlichkeit und nur waehrend der Fahrt - im Mittel einmal in gut sechzehn Minuten. Selten genug, dass man es nicht erwartet; haeufig genug, dass es irgendwann jemand sieht. Wer Bewegungen abbestellt hat, bekommt den Gruss gar nicht erst: ein schleuderndes Auto ist genau das, was damit gemeint ist. Haelt der Wagen mitten im Ausrutscher an, wird die Schale eingesammelt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1165,6 +1165,53 @@ input[type='range']::-webkit-slider-runnable-track {
|
|||||||
to { transform: translateY(472.5px); }
|
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 ----------------------------------------------------------
|
/* --- Fahrtwind ----------------------------------------------------------
|
||||||
Vier Streifen neben dem Wagen, die von vorn nach hinten laufen. Sichtbar
|
Vier Streifen neben dem Wagen, die von vorn nach hinten laufen. Sichtbar
|
||||||
nur, solange zeichneFahrt() dem SVG die Klasse "faehrt" gibt.
|
nur, solange zeichneFahrt() dem SVG die Klasse "faehrt" gibt.
|
||||||
@@ -1222,6 +1269,14 @@ input[type='range']::-webkit-slider-runnable-track {
|
|||||||
.skoda-auto .strasse .leitlinie {
|
.skoda-auto .strasse .leitlinie {
|
||||||
animation: none;
|
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); }
|
.skoda-auto .rad rect { fill: rgba(18, 20, 24, 0.9); }
|
||||||
|
|||||||
@@ -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.
|
* Fahrt anzeigen: Fahrtwind am Fahrzeug, Abzeichen im Kopf der Kachel.
|
||||||
*
|
*
|
||||||
@@ -559,6 +588,9 @@ function zeichneFahrt(w) {
|
|||||||
const bild = $("skodaAuto");
|
const bild = $("skodaAuto");
|
||||||
if (bild) {
|
if (bild) {
|
||||||
bild.classList.toggle("faehrt", w.faehrt);
|
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");
|
const abzeichen = $("skodaUnterwegs");
|
||||||
if (abzeichen) {
|
if (abzeichen) {
|
||||||
@@ -1496,6 +1528,7 @@ document.addEventListener("readystatechange", function () {
|
|||||||
ladeLadungen(); ladeKurve(); ladeFahrten(); ladeStrecke();
|
ladeLadungen(); ladeKurve(); ladeFahrten(); ladeStrecke();
|
||||||
}, 300000);
|
}, 300000);
|
||||||
setInterval(ladeGesundheit, 900000);
|
setInterval(ladeGesundheit, 900000);
|
||||||
|
setInterval(bananeVielleicht, BANANE_TAKT);
|
||||||
|
|
||||||
// Leaflet rechnet die Kachelanordnung selbst neu, sobald es erfährt, dass
|
// Leaflet rechnet die Kachelanordnung selbst neu, sobald es erfährt, dass
|
||||||
// sein Container eine andere Größe hat.
|
// sein Container eine andere Größe hat.
|
||||||
|
|||||||
@@ -108,6 +108,14 @@
|
|||||||
120 Grad versetzt ein. -->
|
120 Grad versetzt ein. -->
|
||||||
<path id="klimaFluegel"
|
<path id="klimaFluegel"
|
||||||
d="M0 0 C 1.5 -4, 5 -7, 7.5 -5 C 9.6 -3.2, 5.5 -0.8, 0 0 Z"/>
|
d="M0 0 C 1.5 -4, 5 -7, 7.5 -5 C 9.6 -3.2, 5.5 -0.8, 0 0 Z"/>
|
||||||
|
|
||||||
|
<!-- Ein Zipfel einer Bananenschale, von oben gesehen und
|
||||||
|
um den eigenen Ansatz im Ursprung gezeichnet. Die
|
||||||
|
Schale setzt ihn dreimal um je 120 Grad versetzt
|
||||||
|
ein - wie das Lüfterrad, nur krummer. -->
|
||||||
|
<path id="bananenZipfel"
|
||||||
|
d="M0 0 C 1 -3.2, 4.5 -6.5, 7.5 -5.2
|
||||||
|
C 9.5 -4.2, 8 -1.2, 3.5 0.6 Z"/>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<!-- Die Straße, über die der Wagen fährt. Ganz zuerst
|
<!-- Die Straße, über die der Wagen fährt. Ganz zuerst
|
||||||
@@ -146,6 +154,23 @@
|
|||||||
<line class="begrenzung" x1="230" y1="-8" x2="230" y2="508"/>
|
<line class="begrenzung" x1="230" y1="-8" x2="230" y2="508"/>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
|
<!-- Ostergruß: ganz selten liegt eine Bananenschale auf
|
||||||
|
der Fahrbahn, und der Wagen kommt kurz ins Schleudern.
|
||||||
|
Ausgelöst wird das in js/solar/skodaMQTT.js, gezeichnet
|
||||||
|
wird es hier.
|
||||||
|
|
||||||
|
Sie liegt zwischen Straße und Fahrzeug im Markup, wird
|
||||||
|
also von der Karosserie verdeckt, sobald der Wagen
|
||||||
|
darüberrollt - so, wie es sich gehört. -->
|
||||||
|
<g class="bananenschale" aria-hidden="true">
|
||||||
|
<g class="schale" transform="translate(95 0) scale(1.4)">
|
||||||
|
<use href="#bananenZipfel"/>
|
||||||
|
<use href="#bananenZipfel" transform="rotate(120)"/>
|
||||||
|
<use href="#bananenZipfel" transform="rotate(240)"/>
|
||||||
|
<circle class="strunk" r="1.6"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
<!-- Fahrtwind: zeigt an, dass das Fahrzeug gerade rollt.
|
<!-- Fahrtwind: zeigt an, dass das Fahrzeug gerade rollt.
|
||||||
Die Streifen laufen von vorn nach hinten, also im Bild
|
Die Streifen laufen von vorn nach hinten, also im Bild
|
||||||
von oben nach unten - das Auto zeigt nach oben.
|
von oben nach unten - das Auto zeigt nach oben.
|
||||||
@@ -172,6 +197,11 @@
|
|||||||
<line class="boe b6" x1="224" y1="-120" x2="224" y2="-70"/>
|
<line class="boe b6" x1="224" y1="-120" x2="224" y2="-70"/>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
|
<!-- Alles ab hier ist das Fahrzeug selbst, zusammengefasst
|
||||||
|
in einer Gruppe: nur so kann es als Ganzes schleudern,
|
||||||
|
ohne die Straße mitzudrehen. -->
|
||||||
|
<g id="wagen">
|
||||||
|
|
||||||
<!-- Räder. Vorderachse bei 860 mm, Hinterachse bei 3625 mm
|
<!-- Räder. Vorderachse bei 860 mm, Hinterachse bei 3625 mm
|
||||||
ab Bugspitze - der Radstand von 2765 mm maßstäblich. -->
|
ab Bugspitze - der Radstand von 2765 mm maßstäblich. -->
|
||||||
<g class="rad">
|
<g class="rad">
|
||||||
@@ -423,6 +453,8 @@
|
|||||||
<title>Klima und Lüftung steuern</title>
|
<title>Klima und Lüftung steuern</title>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
|
</g><!-- /#wagen -->
|
||||||
|
|
||||||
<!-- Der Teil des Fahrtwinds, der über das Fahrzeug zieht.
|
<!-- Der Teil des Fahrtwinds, der über das Fahrzeug zieht.
|
||||||
Eigene Gruppe am Ende des Bildes, weil die Reihenfolge
|
Eigene Gruppe am Ende des Bildes, weil die Reihenfolge
|
||||||
im Markup die Malreihenfolge ist - weiter oben lägen
|
im Markup die Malreihenfolge ist - weiter oben lägen
|
||||||
|
|||||||
Reference in New Issue
Block a user