Liedausschnitte: public/musik/folge08/laternenlied-<sprache>.mp3 (VPS /shared/youtube/musik/folge08/) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
import React from 'react';
|
||
import {Audio, Sequence, interpolate, staticFile, useCurrentFrame} from 'remotion';
|
||
import {ClipFigur, Figur, Kamera} from '../baukasten/figur';
|
||
import {gang} from '../baukasten/gang';
|
||
import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
|
||
import {Funkeln} from '../baukasten/natur';
|
||
import {BODEN} from '../baukasten/orte';
|
||
import {Untertitel} from '../baukasten/untertitel';
|
||
import {Karaoke} from '../lieder/karaoke';
|
||
import {LATERNENLIED} from './laternenlied';
|
||
import {plane} from './plan';
|
||
import {Abenddunkel, GartenAbend, Laterne, laterneInNoasHand} from './teile';
|
||
|
||
// Szene 3: Es wird dunkel. Abendgarten, rechts die Hauswand mit erleuchtetem Fenster.
|
||
// Noa knipst das Lämpchen an (kein Feuer); dann erklingt das gesungene Laternenlied (Suno, je Sprache
|
||
// die zweimal gesungene Strophe, laternenlied.ts) mit Mitlesetext. Noa wiegt sich, die Laterne pendelt im Takt.
|
||
// Pino tippelt zu ihr (baukasten/gang.ts, Füße rutschen nicht). Lulu steht schon an der Hauswand –
|
||
// sie geht nicht durchs Bild, weil ihr Geh-Clip kein echtes Gehen ist.
|
||
|
||
const NOA_X = 760;
|
||
const LULU_X = 1640; // rechts vom Fenster, damit Papa zu sehen ist
|
||
|
||
export const S3 = plane('s3', [
|
||
{id: 'bild0', dauer: 3.0},
|
||
{id: 'e1', wer: 'ERZ'},
|
||
{id: 'klick', dauer: 1.4},
|
||
{id: 'e2', wer: 'ERZ'},
|
||
{id: 'p1', wer: 'PINO'},
|
||
{id: 'e3', wer: 'ERZ'}, // „Kannst du mitsingen?“
|
||
{id: 'lied', dauer: LATERNENLIED.dauer},
|
||
{id: 'bild1', dauer: 1.2},
|
||
]);
|
||
|
||
export const Szene3: React.FC = () => {
|
||
const f = useCurrentFrame();
|
||
const {z, dauer} = S3;
|
||
|
||
const an = z.klick.start + 12;
|
||
const licht = interpolate(f, [an, an + 8], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||
// 84 BPM: die Laterne pendelt im Takt (ein Hin-und-her pro Takt)
|
||
const singt = f >= z.lied.start && f < z.lied.ende;
|
||
const takt = (f - z.lied.start) * ((2 * Math.PI * 84) / 60 / 30 / 2);
|
||
const schwung = singt ? Math.sin(takt) * 7 : Math.sin(f * 0.05) * 2;
|
||
const lat = laterneInNoasHand(NOA_X);
|
||
|
||
// Pino kommt beim Lied dicht an Noas Stiefel (ganze Schritte, Füße bleiben am Boden)
|
||
const PINO = gang('pino', z.lied.start + 20, 220, NOA_X - 300, 2.5); // bleibt links der Laterne stehen, verdeckt sie nicht
|
||
|
||
const kam = kamFahrt(f, [
|
||
[0, 1000, 540, 1.0],
|
||
[z.bild0.ende, 980, 560, 1.06],
|
||
[z.klick.start, 760, 640, 1.55],
|
||
[z.e2.ende, 720, 640, 1.7],
|
||
[z.p1.start + 6, lat.x, lat.y, 2.3], // „Mein Igel leuchtet!“
|
||
[z.p1.ende + 10, 820, 640, 1.35],
|
||
[z.lied.start + 90, 900, 600, 1.2],
|
||
[dauer, 920, 600, 1.15],
|
||
]);
|
||
|
||
return (
|
||
<>
|
||
<Kamera {...kam}>
|
||
<GartenAbend />
|
||
<Figur pose={[[0, 'lulu_A5_blick-links'], [z.p1.start, 'lulu_A3_lachen']]} x={LULU_X} y={BODEN - 6} stauchY={atmen(f, 3, 0.006)} />
|
||
<Figur
|
||
pose={[
|
||
[0, 'noa_A_laterne'],
|
||
]}
|
||
x={NOA_X}
|
||
y={BODEN}
|
||
stauchY={atmen(f, 2)}
|
||
drehung={singt ? Math.sin(takt) * 1.6 : 0}
|
||
/>
|
||
<Laterne x={lat.x} y={lat.y} s={lat.s} licht={licht} schwung={schwung} stab={false} />
|
||
<Funkeln x={lat.x} y={lat.y} start={an} dauer={30} s={0.8} />
|
||
{PINO.geht(f) ? (
|
||
<ClipFigur name="pino_C1_gehen-schleife" start={PINO.clipStart} tempo={PINO.tempo} schleife spiegeln={PINO.spiegeln} x={PINO.x(f)} y={BODEN} />
|
||
) : (
|
||
<Figur
|
||
pose={[
|
||
[0, 'pino_A6_blick-rechts'],
|
||
[an, 'pino_A4_staunen'],
|
||
[z.lied.start, 'pino_A6_blick-rechts'],
|
||
[PINO.ende, 'pino_A3_lachen'],
|
||
]}
|
||
x={PINO.x(f)}
|
||
y={BODEN}
|
||
stauchY={atmen(f, 1)}
|
||
/>
|
||
)}
|
||
<Abenddunkel licht={{x: lat.x, y: lat.y}} staerke={0.55 - 0.15 * licht} radius={380 + 260 * licht} />
|
||
</Kamera>
|
||
<Vignette />
|
||
<Sequence from={z.lied.start} durationInFrames={z.lied.ende - z.lied.start + 6}>
|
||
<Audio src={staticFile(LATERNENLIED.datei)} volume={0.85} />
|
||
<Karaoke zeilen={LATERNENLIED.zeilen} />
|
||
</Sequence>
|
||
<Untertitel zeilen={S3.liste} />
|
||
<Blende dauer={dauer} rein={14} raus={14} />
|
||
</>
|
||
);
|
||
};
|