youtube/remotion/src/kanal/Vorschaubild.tsx
2026-11-07 21:36:46 +00:00

95 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
};