- gemeinsame Bausteine nach src/baukasten/, Bibliothek nach public/bibliothek/, Orte nach public/orte/ - je Szene eine Komposition (F02-01-…), werkzeuge/render.mjs rendert nur geänderte Szenen und klebt sie zusammen; --entwurf mit halber Auflösung und eingeblendeter Zeit/Zeile - werkzeuge/stimmen.mts erzeugt ElevenLabs-Aufnahmen, Zeitplan übernimmt ihre Länge - Folge 2: Geh- und Hinsetz-Clips statt Standbild-Wechsel, neue Vögel, fallendes Blatt, Noa malt den Kalender (Blick von oben) - ANLEITUNG_PC.md für Studio und Rendern unter Windows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
4.3 KiB
TypeScript
124 lines
4.3 KiB
TypeScript
import React from 'react';
|
|
import {useCurrentFrame} from 'remotion';
|
|
import {ClipFigur, Figur, Kamera} from '../baukasten/figur';
|
|
import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
|
|
import {Nest, Schnee, Zzz} from '../baukasten/natur';
|
|
import {BODEN, NEST_X, Ort} from '../baukasten/orte';
|
|
import {Untertitel} from '../baukasten/untertitel';
|
|
import {plane} from './plan';
|
|
|
|
// Szene 7: Gute Nacht, Pino. Nacht im Garten, die erste Schneeflocke fällt.
|
|
|
|
const NOA_X7 = 1140;
|
|
const LULU_X7 = 1800;
|
|
const LATERNE = {x: 1290, y: BODEN + 10};
|
|
|
|
export const S7 = plane('s7',
|
|
[
|
|
{id: 'bild0', dauer: 3.4},
|
|
{id: 'n1', wer: 'NOA', text: 'Schlaf gut, Pino. Nur bis morgen.', leise: true},
|
|
{id: 'e1', wer: 'ERZ', text: 'Ab dem 1. Dezember öffnen Noa, Lulu und Pino jeden Tag ein Türchen.'},
|
|
{id: 'e2', wer: 'ERZ', text: 'Und du kannst mitmachen! Schaffst du es mit Pino bis zum Winterfest?', pause: 3},
|
|
{id: 't1', wer: 'NOA_LULU', text: 'Tschüss! Bis bald!', leise: true, dauer: 2.6},
|
|
{id: 'p1', wer: 'PINO', text: '… bis bald …', leise: true, dauer: 2.6},
|
|
],
|
|
{vorlauf: 0.5, nachlauf: 1.6},
|
|
);
|
|
|
|
const Laterne: React.FC<{frame: number}> = ({frame}) => {
|
|
const flackern = 0.92 + 0.08 * Math.sin(frame * 0.5) * Math.sin(frame * 0.17);
|
|
return (
|
|
<>
|
|
<div style={{position: 'absolute', left: LATERNE.x - 18, top: LATERNE.y - 92, width: 36, height: 8, borderRadius: 3, background: '#3a3036'}} />
|
|
<div style={{position: 'absolute', left: LATERNE.x - 3, top: LATERNE.y - 112, width: 6, height: 22, background: '#3a3036'}} />
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
left: LATERNE.x - 24,
|
|
top: LATERNE.y - 84,
|
|
width: 48,
|
|
height: 70,
|
|
borderRadius: 10,
|
|
background: `radial-gradient(circle at 50% 55%, #fff4c2 0%, #ffc95e ${40 * flackern}%, #e08a3c 100%)`,
|
|
border: '5px solid #3a3036',
|
|
}}
|
|
/>
|
|
<div style={{position: 'absolute', left: LATERNE.x - 30, top: LATERNE.y - 16, width: 60, height: 12, borderRadius: 4, background: '#3a3036'}} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const Szene7: React.FC = () => {
|
|
const f = useCurrentFrame();
|
|
const {z, dauer} = S7;
|
|
const flackern = 0.92 + 0.08 * Math.sin(f * 0.5) * Math.sin(f * 0.17);
|
|
const winken = z.t1.start - 6;
|
|
|
|
const kam = kamFahrt(f, [
|
|
[0, 1300, 600, 1.15],
|
|
[z.bild0.ende, 1350, 700, 1.4],
|
|
[z.n1.ende, NEST_X, 820, 2.0],
|
|
[z.e2.start, 1380, 700, 1.45],
|
|
[z.t1.start, 1400, 680, 1.4],
|
|
[z.p1.start, NEST_X, 850, 2.6],
|
|
[dauer, NEST_X, 860, 2.9],
|
|
]);
|
|
|
|
return (
|
|
<>
|
|
<Kamera {...kam}>
|
|
<Ort name="garten_nacht" />
|
|
<div style={{position: 'absolute', inset: 0, filter: 'brightness(0.62) saturate(0.8) hue-rotate(-8deg)'}}>
|
|
{f < winken ? (
|
|
<Figur
|
|
pose={[
|
|
[0, 'noa_A6_blick-rechts'],
|
|
[z.bild0.ende - 20, 'noa_A2_augen-halb'],
|
|
[z.e1.start, 'noa_A3_lachen'],
|
|
]}
|
|
x={NOA_X7}
|
|
y={BODEN}
|
|
stauchY={atmen(f, 2)}
|
|
/>
|
|
) : (
|
|
<ClipFigur name="noa_C4_winken" start={winken} tempo={1.2} x={NOA_X7} y={BODEN} />
|
|
)}
|
|
<Nest x={NEST_X} y={BODEN} seite="hinten" />
|
|
<div style={{position: 'absolute', inset: 0, clipPath: `inset(0 0 ${1080 - BODEN - 4}px 0)`}}>
|
|
<Figur pose="pino_B_schlaeft-eingerollt" x={NEST_X + 10} y={BODEN - 34} stauchY={atmen(f, 1, 0.02)} schatten={false} />
|
|
</div>
|
|
<Nest x={NEST_X} y={BODEN} seite="vorne" />
|
|
<Figur
|
|
pose={[
|
|
[0, 'lulu_A5_blick-links'],
|
|
[z.bild0.ende, 'lulu_A2_augen-halb'],
|
|
[z.t1.start, 'lulu_A3_lachen'],
|
|
]}
|
|
x={LULU_X7}
|
|
y={BODEN - 10}
|
|
stauchY={atmen(f, 3, 0.006)}
|
|
drehung={f > z.t1.start && f < z.t1.ende ? Math.sin((f - z.t1.start) * 0.25) * 2 : 0}
|
|
/>
|
|
</div>
|
|
{/* warmes Licht der Laterne */}
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
left: LATERNE.x - 520,
|
|
top: LATERNE.y - 560,
|
|
width: 1040,
|
|
height: 900,
|
|
background: `radial-gradient(closest-side, rgba(255, 200, 110, ${0.42 * flackern}), rgba(255, 180, 90, 0.12) 55%, rgba(255, 180, 90, 0) 100%)`,
|
|
mixBlendMode: 'screen',
|
|
}}
|
|
/>
|
|
<Laterne frame={f} />
|
|
<Zzz x={NEST_X + 50} y={BODEN - 110} start={20} s={0.7} />
|
|
<Schnee start={30} ziel={[NEST_X - 20, BODEN - 70]} />
|
|
</Kamera>
|
|
<Vignette staerke={0.5} />
|
|
<Untertitel zeilen={S7.liste} />
|
|
<Blende dauer={dauer} rein={16} raus={0} farbe="#1c1a24" />
|
|
</>
|
|
);
|
|
};
|