youtube/remotion/src/folge02/szene6.tsx

179 lines
5.9 KiB
TypeScript

import React from 'react';
import {useCurrentFrame} from 'remotion';
import {kurve} from '../bewegung';
import {ClipFigur, Figur, Kamera} from '../baukasten/figur';
import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
import {Funkeln} from '../baukasten/natur';
import {KALENDER_TUER1, KalenderAufTisch, KalenderMalen, Ort} from '../baukasten/orte';
import {Untertitel} from '../baukasten/untertitel';
import {plane} from './plan';
// Szene 6: Noas Idee. Abends in Noas Zimmer, Noa malt den Kalender.
const N = 420; // Noas Größe im Zimmer (näher an der Kamera)
const NOA_X6 = 800;
const PINO_X6 = 1090;
const TISCH_Y = 802;
const LULU_X6 = 1440;
export const S6 = plane('s6', [
{id: 'bild0', dauer: 3.0},
{id: 'malen', dauer: 5.5},
{id: 'l1', wer: 'LULU', text: 'Was malst du da, Noa?'},
{id: 'n1', wer: 'NOA', text: 'Einen Kalender! Mit 24 Türchen.'},
{id: 'n2', wer: 'NOA', text: 'Wir öffnen jeden Tag eins. Und hinter jedem Türchen steckt etwas, das Pino wach hält.'},
{id: 'p1', wer: 'PINO', text: 'Was denn?'},
{id: 'n3', wer: 'NOA', text: 'Etwas zum Entdecken, zum Basteln, zum Backen und zum Singen.'},
{id: 'n4', wer: 'NOA', text: 'Und wenn das letzte Türchen offen ist, ist Winterfest!'},
{id: 'bild1', dauer: 2.0},
{id: 'p2', wer: 'PINO', text: 'Meine Stacheln kribbeln!'},
{id: 'bild2', dauer: 4.2},
]);
export const Szene6: React.FC = () => {
const f = useCurrentFrame();
const {z, dauer} = S6;
// Noa malt: Blick von oben aufs Blatt, während „malen“ und während sie antwortet (n1).
// Langsamer Anfang, dazwischen Zimmer (es geht weiter), bei n1 ist er fast fertig.
const malP = kurve(f, [
[z.malen.start, 0],
[z.malen.start + 50, 0.03],
[z.malen.ende, 0.2],
[z.n1.start, 0.8],
[z.n1.ende, 0.96],
]);
const malSicht = (f >= z.malen.start && f < z.l1.start) || (f >= z.n1.start && f < z.n1.ende + 6);
const malt = f < z.n1.ende;
const luluX = kurve(f, [
[20, 1900],
[z.bild0.ende, LULU_X6],
]);
const sprung = z.bild1.start;
const imSprung = f >= sprung && f < sprung + 58;
const kribbeln = f > z.p2.start - 5 && f < z.p2.ende + 10;
const zitter = kribbeln ? Math.sin(f * 2.3) * 3 : 0;
const kalender = f >= z.bild2.start;
const tippen = [z.bild2.start + 45, z.bild2.start + 75];
const tippY = tippen.reduce((s, t) => s + Math.max(0, Math.sin(Math.min(1, Math.max(0, (f - t) / 14)) * Math.PI)) * 30, 0);
const leuchten = kalender ? 0.5 + 0.5 * Math.sin((f - z.bild2.start) * 0.15) : 0;
const kam = kamFahrt(f, [
[0, 960, 540, 1.0],
[z.bild0.ende, 1060, 560, 1.15],
[z.l1.start, 1080, 640, 1.5],
[z.n1.ende, 1060, 650, 1.5],
[z.p1.start, 980, 650, 1.6],
[z.n4.ende, 960, 640, 1.5],
[sprung + 10, 1050, 700, 2.0],
[z.p2.ende, 1060, 710, 2.1],
]);
const kalKam = kamFahrt(f, [
[z.bild2.start, 960, 540, 1.0],
[dauer, KALENDER_TUER1.x - 40, KALENDER_TUER1.y, 1.6],
]);
if (malSicht) {
return (
<>
<Kamera x={kurve(f, [[z.malen.start, 900], [z.n1.ende, 1020]])} y={560} zoom={1.12}>
<Ort name="kalender_leer" />
<KalenderMalen p={malP} wackeln={f} />
</Kamera>
<Vignette />
<Untertitel zeilen={S6.liste} />
</>
);
}
if (kalender) {
return (
<>
<Kamera {...kalKam}>
<Ort name="kalender" />
<div
style={{
position: 'absolute',
left: KALENDER_TUER1.x - 110,
top: KALENDER_TUER1.y - 95,
width: 220,
height: 190,
borderRadius: 26,
boxShadow: `0 0 ${30 + 30 * leuchten}px ${10 + 10 * leuchten}px rgba(255, 210, 90, ${0.35 + 0.35 * leuchten})`,
transform: 'rotate(-2deg)',
}}
/>
{/* Buntstift tippt auf Türchen 1 */}
<div
style={{
position: 'absolute',
left: KALENDER_TUER1.x + 10,
top: KALENDER_TUER1.y - 330 - tippY + 30,
width: 36,
height: 300,
transform: 'rotate(18deg)',
transformOrigin: '50% 100%',
}}
>
<div style={{position: 'absolute', bottom: 0, left: 6, width: 0, height: 0, borderLeft: '12px solid transparent', borderRight: '12px solid transparent', borderTop: '0', borderBottom: '40px solid #f1d2a6', transform: 'rotate(180deg)'}} />
<div style={{position: 'absolute', bottom: 40, left: 0, width: 36, height: 260, borderRadius: 6, background: 'linear-gradient(90deg, #b93f3b, #d9534f 40%, #b93f3b)'}} />
</div>
<Funkeln x={KALENDER_TUER1.x} y={KALENDER_TUER1.y} start={tippen[1] + 6} dauer={40} s={1.3} />
</Kamera>
<Vignette />
<Untertitel zeilen={S6.liste} />
<Blende dauer={dauer} rein={0} raus={14} />
</>
);
}
return (
<>
<Kamera {...kam}>
<Ort name="zimmer_himmel" />
<Figur pose={[[0, 'lulu_A5_blick-links'], [z.n2.start, 'lulu_A3_lachen'], [z.p2.start, 'lulu_A3_lachen']]} x={luluX} y={1180} hoehe={N * 2.05} schatten={false} />
<Ort name="zimmer_wand" />
<Figur
pose={[
[0, 'noa_B_sitzt'],
[z.n1.start, 'noa_B_sitzt'],
]}
x={NOA_X6}
y={1000}
hoehe={N}
stauchY={atmen(f, 2)}
drehung={malt ? Math.sin(f * 0.3) * 0.8 : 0}
schatten={false}
/>
<Ort name="zimmer_tisch" />
{f >= z.malen.start && <KalenderAufTisch p={malP} />}
{imSprung ? (
<ClipFigur name="pino_C3_freudensprung" start={sprung} tempo={1.4} x={PINO_X6} y={TISCH_Y} hoehe={N * 0.4} />
) : (
<Figur
pose={[
[0, 'pino_A5_blick-links'],
[z.l1.start + 10, 'pino_A6_blick-rechts'],
[z.n1.start + 10, 'pino_A5_blick-links'],
[z.p1.start, 'pino_A4_staunen'],
[z.n3.start + 20, 'pino_A5_blick-links'],
[z.n4.start + 30, 'pino_A3_lachen'],
]}
x={PINO_X6 + zitter}
y={TISCH_Y + (kribbeln ? huepfer(f, z.p2.start, 12, 10) + huepfer(f, z.p2.start + 14, 12, 10) : 0)}
hoehe={N * 0.4}
drehung={zitter}
stauchY={atmen(f, 1)}
/>
)}
{kribbeln && <Funkeln x={PINO_X6} y={TISCH_Y - 120} start={z.p2.start} dauer={40} s={0.8} />}
</Kamera>
<Vignette />
<Untertitel zeilen={S6.liste} />
<Blende dauer={dauer} rein={14} raus={0} />
</>
);
};