diff --git a/remotion/src/lieder/lied03/Lied03.tsx b/remotion/src/lieder/lied03/Lied03.tsx index f19f476..02181d9 100644 --- a/remotion/src/lieder/lied03/Lied03.tsx +++ b/remotion/src/lieder/lied03/Lied03.tsx @@ -53,6 +53,14 @@ const KAMERA: [number, number, number, number][] = [ [T.c5, 1120, 660, 1.3], [T.ende, 1120, 640, 1.2], ]; +// Orte der Strophen (Überblendung 0,8 s); ES/FR haben keine Strophe 4 +const ORTE = [ + {name: 'garten', von: T.v1 - 0.4, bis: T.c2 - 0.4}, // Apfel und Blume: Garten mit Holzstapel + {name: 'waldrand', von: T.v2 - 0.4, bis: T.c3 - 0.4}, // laut/leise und schnell/langsam: am Waldrand + ...(T.v4 !== undefined ? [{name: 'garten', von: T.v4 - 0.4, bis: T.m - 0.4}] : []), + {name: 'oben', von: T.gag - 0.4, bis: T.c4 - 0.4}, // Gag: auf der Wiese mit den kahlen Bäumen +]; + const kamera = (f: number) => { const p: [number, number, number, number][] = []; KAMERA.forEach(([t, x, y, z], i) => { @@ -244,7 +252,21 @@ const Garten: React.FC = () => { const noaZeigtLinks = karte >= 0 && KARTEN[karte].zeigt[f >= s(KARTEN[karte].antwort - 0.2) ? 1 : 0] === 'links'; // Strophe 1: Pino pflückt die Blume – sie fliegt in seine Pfote und bleibt dort bis in Refrain 2 const pflueck = interpolate(f, [s(T.v1z[3]), s(T.v1z[3] + 0.8)], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); - const blumeBeiPino = imAbschnitt(f, T.v1z[3], T.c2 + 9); + // … und legt sie zu Beginn von Refrain 2 neben sich ins Gras, wo sie verblasst + const blumeBeiPino = imAbschnitt(f, T.v1z[3], T.c2 + 3); + const ablegen = interpolate(f, [s(T.c2 - 0.3), s(T.c2 + 0.5)], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + const blumeWeg = interpolate(f, [s(T.c2 + 1.5), s(T.c2 + 3)], [1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + + // Strophe 3: Stampfen im Takt – Noa und Lulu treten auf, alle federn beim Aufsetzen ein + // („Stampf mit mir“: jeder Schlag, „Stampf ganz langsam“: jeder zweite Schlag) + const stampfPhase = (von: number, bis: number, jeden: number) => { + if (!imAbschnitt(f, von, bis)) return 0; + const p = (((f - s(von)) / (SCHLAG * jeden)) % 1 + 1) % 1; + return p < 0.35 ? Math.sin((p / 0.35) * Math.PI) : 0; // kurzer Hub, dann Aufsetzen + }; + const stampf = Math.max(stampfPhase(T.v3z[1], T.v3z[2], 1), stampfPhase(T.v3z[3], T.c3, 2)); + const stampfHub = -24 * stampf; + const einfedern = 1 - 0.06 * (stampf > 0 ? 1 - stampf : 0); const pinoGross = interpolate(f, [s(T.gag + 1), s(T.gag + 1.6), s(T.c4 - 0.6), s(T.c4)], [1, 1.25, 1.25, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); // Gag: Pino und Lulu rücken zusammen („Nase an Nase“) const gagNah = interpolate(f, [s(T.gag + 3), s(T.gag + 4.5), s(T.c4 - 0.8), s(T.c4)], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); @@ -262,6 +284,15 @@ const Garten: React.FC = () => { <> + {/* Abwechslung: jede Strophe an einem anderen Ort, Refrains im Herbstgarten */} + {ORTE.map((o) => { + const sicht = interpolate(f, [s(o.von) - 18, s(o.von) + 6, s(o.bis) - 6, s(o.bis) + 18], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + return sicht > 0 ? ( +
+ +
+ ) : null; + })}
@@ -278,13 +309,13 @@ const Garten: React.FC = () => { )} - + {flitzen ? ( ) : ( @@ -298,7 +329,11 @@ const Garten: React.FC = () => { blende={8} /> )} - {blumeBeiPino && } + {blumeBeiPino && ( +
+ +
+ )} {imAbschnitt(f, T.v2 - 0.3, T.v2z[2]) && }