95 lines
3.8 KiB
TypeScript
95 lines
3.8 KiB
TypeScript
import React from 'react';
|
||
import {AbsoluteFill} from 'remotion';
|
||
import {Figur, GROESSE, Kamera, NOA_HOEHE} from '../baukasten/figur';
|
||
import {Drachen, drachenHalt} from '../baukasten/drachen';
|
||
import {Drachenschnur, spulenPunkt} from '../baukasten/drachenschnur';
|
||
import {WindGarten} from '../folge09/teile';
|
||
import {Vignette} from '../baukasten/helfer';
|
||
import {Apfel, Blume} from '../baukasten/natur';
|
||
import {BODEN, Ort} from '../baukasten/orte';
|
||
import {SPRACHE, type Sprache} from '../baukasten/sprache';
|
||
import {SCHRIFT} from '../baukasten/untertitel';
|
||
|
||
// Vorschaubild (Thumbnail) für Folge 1 „Zu klein, zu groß“, je Sprache:
|
||
// npx remotion still src/index.ts Vorschau-F01 /shared/youtube/vorschaubilder/folge01-de.png --scale=0.6667
|
||
// … --props='{"sprache":"es"}'
|
||
// Gebaut in 1920 × 1080, ausgegeben mit --scale=0.6667 als 1280 × 720 (YouTube-Empfehlung).
|
||
// Pino streckt sich zum Apfel (zu klein), Lulu beugt sich zur Blume (zu groß), Noa lacht in der Mitte.
|
||
// Schrift kurz und groß, damit sie auch in der kleinen Vorschau auf dem Handy lesbar bleibt.
|
||
|
||
const TEXT: Record<Sprache, [string, string]> = {
|
||
de: ['Zu klein?', 'Zu groß?'],
|
||
es: ['¿Muy pequeño?', '¿Muy alta?'],
|
||
fr: ['Trop petit ?', 'Trop grande ?'],
|
||
};
|
||
|
||
const Zeile: React.FC<{text: string; farbe: string; groesse?: number}> = ({text, farbe, groesse = 150}) => (
|
||
<div
|
||
style={{
|
||
fontFamily: SCHRIFT,
|
||
fontWeight: 700,
|
||
fontSize: groesse,
|
||
lineHeight: 1,
|
||
color: farbe,
|
||
WebkitTextStroke: '14px #fbf4e4',
|
||
paintOrder: 'stroke fill',
|
||
textShadow: '0 10px 30px rgba(60,40,20,0.35)',
|
||
whiteSpace: 'nowrap',
|
||
}}
|
||
>
|
||
{text}
|
||
</div>
|
||
);
|
||
|
||
export const VorschauF01: React.FC = () => {
|
||
const [oben, unten] = TEXT[SPRACHE];
|
||
return (
|
||
<AbsoluteFill style={{background: '#f4ead8'}}>
|
||
<Kamera x={1010} y={590} zoom={1.42}>
|
||
<Ort name="garten_herbst" />
|
||
<Apfel x={660} y={520} s={1.5} r={-8} />
|
||
<Figur pose="pino_A_hinterbeine" x={700} y={BODEN} />
|
||
<Figur pose="noa_A3_lachen" x={1010} y={BODEN} />
|
||
<Blume x={1180} y={BODEN - 4} s={1.2} />
|
||
<Figur pose="lulu_A_hals-unten" x={1480} y={BODEN - 6} />
|
||
</Kamera>
|
||
<Vignette staerke={0.25} />
|
||
<div style={{position: 'absolute', top: 40, left: 60, display: 'flex', flexDirection: 'column', gap: 6}}>
|
||
<Zeile text={oben} farbe="#3f5a8a" />
|
||
<Zeile text={unten} farbe="#c8502c" />
|
||
</div>
|
||
</AbsoluteFill>
|
||
);
|
||
};
|
||
|
||
// Vorschaubild für Folge 9 „Lulu und der Drachen“ (Composition Vorschau-F09, Aufruf wie oben):
|
||
// Der rote Drachen steht hoch oben rechts im Wind, die Schnur läuft zu Noas Spule; Lulu lacht mit wehendem
|
||
// Schal, Pino zeigt nach oben. Schrift oben links über dem Himmel.
|
||
const TEXT_F09: Record<Sprache, [string, string]> = {
|
||
de: ['Flieg,', 'Drachen!'],
|
||
es: ['¡Vuela,', 'cometa!'],
|
||
fr: ['Vole,', 'cerf-volant !'],
|
||
};
|
||
|
||
const DRACHEN_F09 = {x: 1580, y: 330, s: 1.5, drehung: 10};
|
||
|
||
export const VorschauF09: React.FC = () => {
|
||
const [oben, unten] = TEXT_F09[SPRACHE];
|
||
return (
|
||
<AbsoluteFill style={{background: '#f4ead8'}}>
|
||
<Kamera x={1080} y={560} zoom={1.3}>
|
||
<WindGarten />
|
||
<Figur pose="pino_A_zeigt" x={760} y={BODEN} />
|
||
<Figur pose="lulu_A3_lachen" x={1070} y={BODEN - 6} />
|
||
<Figur pose="noa_A_drachenschnur" x={1370} y={BODEN} />
|
||
<Drachenschnur von={spulenPunkt(1370, BODEN, NOA_HOEHE * GROESSE.noa, false)} nach={drachenHalt(DRACHEN_F09.x, DRACHEN_F09.y, DRACHEN_F09.s, DRACHEN_F09.drehung)} durchhang={0.05} />
|
||
<Drachen {...DRACHEN_F09} schwanz={24} flattern={14} frame={20} />
|
||
</Kamera>
|
||
<Vignette staerke={0.25} />
|
||
<div style={{position: 'absolute', top: 40, left: 60, display: 'flex', flexDirection: 'column', gap: 6}}>
|
||
<Zeile text={oben} farbe="#3f5a8a" />
|
||
<Zeile text={unten} farbe="#c8502c" groesse={unten.length > 10 ? 100 : 150} />
|
||
</div>
|
||
</AbsoluteFill>
|
||
);
|
||
};
|