Folge 2, Rückmeldung 2: Pino läuft ins Bild, Kichern/Vorbeugen statt Rutschen, Bommel heil, Vögel schlagen immer, Blatt bleibt zwischen Szene 3 und 4, Lulus Blätter fliegen ins Maul, langsameres Malen mit Zimmer-Zwischenbild
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 54 KiB |
|
|
@ -28,7 +28,8 @@ export const punkt = (figur: FigurName, x: number, y: number, cx: number, cy: nu
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bekannte Punkte in der Leinwand (gemessen an den Standbildern)
|
// Bekannte Punkte in der Leinwand (gemessen an den Standbildern)
|
||||||
export const LULU_MAUL_LINKS = {cx: 690, cy: 140}; // lulu_A5 (Blick links)
|
export const LULU_MAUL_LINKS = {cx: 692, cy: 170}; // lulu_A5 (Blick links)
|
||||||
|
export const LULU_MAUL_A1 = {cx: 597, cy: 167}; // lulu_A1 (Augen zu)
|
||||||
export const LULU_KOPF = {cx: 714, cy: 95};
|
export const LULU_KOPF = {cx: 714, cy: 95};
|
||||||
export const PINO_KOPF = {cx: 640, cy: 260};
|
export const PINO_KOPF = {cx: 640, cy: 260};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,10 +98,9 @@ export const Voegel: React.FC<{start: number; anzahl?: number; skala?: number}>
|
||||||
const reihe = Math.ceil(i / 2) * (i % 2 ? 1 : -1); // Spitze vorn, Äste nach hinten
|
const reihe = Math.ceil(i / 2) * (i % 2 ? 1 : -1); // Spitze vorn, Äste nach hinten
|
||||||
const x = 160 + t * 5.5 - Math.abs(reihe) * 75 * skala + r('x') * 20;
|
const x = 160 + t * 5.5 - Math.abs(reihe) * 75 * skala + r('x') * 20;
|
||||||
const y = 600 - t * 1.5 + reihe * 42 * skala + Math.sin(t * 0.05 + r('w') * 6) * 8;
|
const y = 600 - t * 1.5 + reihe * 42 * skala + Math.sin(t * 0.05 + r('w') * 6) * 8;
|
||||||
// Flügelschlag mit kurzen Gleitphasen
|
// Flügelschlag ohne Pause, je Vogel etwas anders schnell
|
||||||
const takt = t * 0.38 + r('p') * 6;
|
const takt = t * (0.34 + r('f') * 0.1) + r('p') * 6;
|
||||||
const gleiten = Math.sin(t * 0.02 + r('q') * 6) > 0.6;
|
const schlag = Math.sin(takt);
|
||||||
const schlag = gleiten ? 0.15 : Math.sin(takt);
|
|
||||||
const g = (34 + r('g') * 8) * skala * (1 - Math.abs(reihe) * 0.03);
|
const g = (34 + r('g') * 8) * skala * (1 - Math.abs(reihe) * 0.03);
|
||||||
return <Vogel key={i} x={x} y={y} g={g} schlag={schlag} neigung={-12 + Math.cos(takt) * 3} />;
|
return <Vogel key={i} x={x} y={y} g={g} schlag={schlag} neigung={-12 + Math.cos(takt) * 3} />;
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -355,6 +355,32 @@ export const KalenderSVG: React.FC<{leer?: boolean}> = ({leer = false}) => {
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
// Der Kalender auf dem Papierbogen am Tisch (Zimmer-Ansicht), Fortschritt p wie KalenderMalen.
|
||||||
|
const PAPIER = [[560, 790], [900, 784], [930, 822], [540, 828]];
|
||||||
|
const aufPapier = (u: number, v: number) => {
|
||||||
|
const [a, b, c, d] = PAPIER;
|
||||||
|
const ox = a[0] + (b[0] - a[0]) * u, oy = a[1] + (b[1] - a[1]) * u;
|
||||||
|
const ux = d[0] + (c[0] - d[0]) * u, uy = d[1] + (c[1] - d[1]) * u;
|
||||||
|
return `${ox + (ux - ox) * v},${oy + (uy - oy) * v}`;
|
||||||
|
};
|
||||||
|
export const KalenderAufTisch: React.FC<{p: number}> = ({p}) => {
|
||||||
|
const tp = Math.min(1, p / 0.08);
|
||||||
|
const tuerP = Math.max(0, (p - 0.08) / 0.92) * 24;
|
||||||
|
const viereck = (u0: number, v0: number, u1: number, v1: number) => [aufPapier(u0, v0), aufPapier(u1, v0), aufPapier(u1, v1), aufPapier(u0, v1)].join(' ');
|
||||||
|
return (
|
||||||
|
<svg viewBox={`0 0 ${B} ${H}`} style={{position: 'absolute', inset: 0, width: '100%', height: '100%'}}>
|
||||||
|
<polygon points={viereck(0.25, 0.1, 0.25 + 0.5 * tp, 0.2)} fill="#c8642c" opacity={0.8} />
|
||||||
|
{new Array(24).fill(0).map((_, i) => {
|
||||||
|
const anteil = Math.min(1, tuerP - i);
|
||||||
|
if (anteil <= 0) return null;
|
||||||
|
const u0 = 0.1 + (i % 6) * 0.135;
|
||||||
|
const v0 = 0.3 + Math.floor(i / 6) * 0.17;
|
||||||
|
return <polygon key={i} points={viereck(u0, v0, u0 + 0.11 * Math.max(0.3, anteil), v0 + 0.13)} fill={kTuer(i).farbe} opacity={0.85} />;
|
||||||
|
})}
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const KALENDER_TUER1 = {x: 330 + 4 * 215 + 90, y: 250 + 1 * 180 + 75}; // Türchen „1“ (Index 10)
|
export const KALENDER_TUER1 = {x: 330 + 4 * 215 + 90, y: 250 + 1 * 180 + 75}; // Türchen „1“ (Index 10)
|
||||||
|
|
||||||
// Noa malt den Kalender (Blick von oben auf das Blatt, über `kalender_leer`).
|
// Noa malt den Kalender (Blick von oben auf das Blatt, über `kalender_leer`).
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,14 @@ export const Szene2: React.FC = () => {
|
||||||
const f = useCurrentFrame();
|
const f = useCurrentFrame();
|
||||||
const {z, dauer} = S2;
|
const {z, dauer} = S2;
|
||||||
|
|
||||||
// Pino kommt von rechts getippelt und setzt sich
|
// Pino kommt von rechts (außerhalb des Bildes) getippelt und setzt sich
|
||||||
const pinoAn = z.bild1.ende + 6;
|
const pinoAn = z.bild1.ende + 6;
|
||||||
|
const pinoLos = z.bild1.start - 120;
|
||||||
const pinoX = kurve(f, [
|
const pinoX = kurve(f, [
|
||||||
[z.bild1.start - 10, 1560],
|
[pinoLos, 2000],
|
||||||
[pinoAn, PINO_X],
|
[pinoAn, PINO_X],
|
||||||
]);
|
]);
|
||||||
|
const pinoDa = f >= pinoLos;
|
||||||
const pinoGeht = f < pinoAn;
|
const pinoGeht = f < pinoAn;
|
||||||
const schreck = z.bild3.start;
|
const schreck = z.bild3.start;
|
||||||
const pinoPose: [number, string][] = [
|
const pinoPose: [number, string][] = [
|
||||||
|
|
@ -77,10 +79,6 @@ export const Szene2: React.FC = () => {
|
||||||
const noaX = kurve(f, [
|
const noaX = kurve(f, [
|
||||||
[z.bild1.start + 10, -180],
|
[z.bild1.start + 10, -180],
|
||||||
[noaAn, NOA_X],
|
[noaAn, NOA_X],
|
||||||
[z.n2.start, NOA_X],
|
|
||||||
[z.n2.start + 20, NOA_X + 60],
|
|
||||||
[z.p3.ende, NOA_X + 60],
|
|
||||||
[z.p3.ende + 30, NOA_X + 20],
|
|
||||||
]);
|
]);
|
||||||
const noaGeht = f > z.bild1.start + 10 && f < noaAn;
|
const noaGeht = f > z.bild1.start + 10 && f < noaAn;
|
||||||
const noaPose: [number, string][] = [
|
const noaPose: [number, string][] = [
|
||||||
|
|
@ -92,9 +90,22 @@ export const Szene2: React.FC = () => {
|
||||||
[z.p3.start + 10, 'noa_A3_lachen'],
|
[z.p3.start + 10, 'noa_A3_lachen'],
|
||||||
[z.e4.start, 'noa_A6_blick-rechts'],
|
[z.e4.start, 'noa_A6_blick-rechts'],
|
||||||
];
|
];
|
||||||
// Kichern: schnelles kleines Hüpfen
|
// Kichern: schwillt an und ab, kleine Hüpfer mit Wiegen und Stauchen
|
||||||
const kichern = f > z.bild2.start + 15 && f < z.bild2.ende ? -Math.abs(Math.sin(f * 0.5)) * 6 : 0;
|
const kichA = z.bild2.start + 15;
|
||||||
const noaY = BODEN + kichern + huepfer(f, z.n1.start, 18, 10);
|
const kichE = z.bild2.ende;
|
||||||
|
const kichHuell = f > kichA && f < kichE ? Math.sin(((f - kichA) / (kichE - kichA)) * Math.PI) : 0;
|
||||||
|
const kichPhase = (f - kichA) * (0.42 + 0.08 * Math.sin((f - kichA) * 0.05));
|
||||||
|
const kichern = -Math.abs(Math.sin(kichPhase)) * 7 * kichHuell;
|
||||||
|
const kichStauch = 1 - 0.035 * Math.abs(Math.cos(kichPhase)) * kichHuell;
|
||||||
|
const kichDreh = (Math.sin(kichPhase * 0.5) * 2.5 + 2) * kichHuell;
|
||||||
|
// „Pino? Pino!“: Noa beugt sich zu Pino hinüber
|
||||||
|
const vorbeugen = kurve(f, [
|
||||||
|
[z.n2.start, 0],
|
||||||
|
[z.n2.start + 14, 1],
|
||||||
|
[z.p3.start, 1],
|
||||||
|
[z.p3.start + 16, 0],
|
||||||
|
]);
|
||||||
|
const noaY = BODEN + kichern + huepfer(f, z.n1.start, 18, 10) + huepfer(f, z.n2.start + 30, 8, 10);
|
||||||
|
|
||||||
const kam = kamFahrt(f, [
|
const kam = kamFahrt(f, [
|
||||||
[0, 960, 540, 1.02],
|
[0, 960, 540, 1.02],
|
||||||
|
|
@ -114,8 +125,8 @@ export const Szene2: React.FC = () => {
|
||||||
<>
|
<>
|
||||||
<Kamera {...kam}>
|
<Kamera {...kam}>
|
||||||
<Ort name="garten" />
|
<Ort name="garten" />
|
||||||
{noaGeht ? <Geher figur="noa" spiegeln x={noaX} y={BODEN} /> : <Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2)} />}
|
{noaGeht ? <Geher figur="noa" spiegeln x={noaX} y={BODEN} /> : <Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2) * kichStauch * (1 + 0.02 * vorbeugen)} drehung={kichDreh + 7 * vorbeugen} />}
|
||||||
{pinoGeht ? <Geher figur="pino" x={pinoX} y={BODEN} tempo={1.3} /> : <Figur pose={pinoPose} x={pinoX} y={pinoY} stauchY={pinoStauchY} drehung={pinoDreh} blende={4} />}
|
{!pinoDa ? null : pinoGeht ? <Geher figur="pino" x={pinoX} y={BODEN} tempo={1.8} /> : <Figur pose={pinoPose} x={pinoX} y={pinoY} stauchY={pinoStauchY} drehung={pinoDreh} blende={4} />}
|
||||||
<Zzz x={PINO_X + 40} y={BODEN - 150} start={z.p2.ende} ende={schreck} s={0.7} />
|
<Zzz x={PINO_X + 40} y={BODEN - 150} start={z.p2.ende} ende={schreck} s={0.7} />
|
||||||
</Kamera>
|
</Kamera>
|
||||||
<Blaetterwind anzahl={6} />
|
<Blaetterwind anzahl={6} />
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const S3 = plane('s3', [
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Das große Blatt, auf das Pino sich setzt
|
// Das große Blatt, auf das Pino sich setzt
|
||||||
const GROSSES_BLATT_X = PINO_X + 50;
|
export const GROSSES_BLATT_X = PINO_X + 50;
|
||||||
|
|
||||||
export const Szene3: React.FC = () => {
|
export const Szene3: React.FC = () => {
|
||||||
const f = useCurrentFrame();
|
const f = useCurrentFrame();
|
||||||
|
|
@ -116,7 +116,7 @@ export const Szene3: React.FC = () => {
|
||||||
// Noa kniet sich zu Pino
|
// Noa kniet sich zu Pino
|
||||||
const knien = z.bild3.start + 10;
|
const knien = z.bild3.start + 10;
|
||||||
const noaX = kurve(f, [
|
const noaX = kurve(f, [
|
||||||
[knien - 36, NOA_X + 20],
|
[knien - 36, NOA_X],
|
||||||
[knien, NOA_X + 140],
|
[knien, NOA_X + 140],
|
||||||
]);
|
]);
|
||||||
const noaPose: [number, string][] = [
|
const noaPose: [number, string][] = [
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ import React from 'react';
|
||||||
import {useCurrentFrame} from 'remotion';
|
import {useCurrentFrame} from 'remotion';
|
||||||
import {kurve} from '../bewegung';
|
import {kurve} from '../bewegung';
|
||||||
import {Figur, Geher, Kamera, NOA_HOCKE_FRAMES, NoaHocke} from '../baukasten/figur';
|
import {Figur, Geher, Kamera, NOA_HOCKE_FRAMES, NoaHocke} from '../baukasten/figur';
|
||||||
import {Blende, LULU_MAUL_LINKS, Vignette, atmen, hopfStauch, huepfer, kamFahrt, punkt, ruck} from '../baukasten/helfer';
|
import {Blende, LULU_MAUL_A1, LULU_MAUL_LINKS, Vignette, atmen, hopfStauch, huepfer, kamFahrt, punkt, ruck} from '../baukasten/helfer';
|
||||||
import {Blaetterregen, Blatt, LAUB, Nest, Ruf} from '../baukasten/natur';
|
import {Blaetterregen, Blatt, LAUB, Nest, Ruf} from '../baukasten/natur';
|
||||||
import {BODEN, NEST_X, Ort} from '../baukasten/orte';
|
import {BODEN, NEST_X, Ort} from '../baukasten/orte';
|
||||||
import {NOA_X, PINO_X} from './szene2';
|
import {NOA_X, PINO_X} from './szene2';
|
||||||
|
import {GROSSES_BLATT_X} from './szene3';
|
||||||
import {Untertitel} from '../baukasten/untertitel';
|
import {Untertitel} from '../baukasten/untertitel';
|
||||||
import {plane} from './plan';
|
import {plane} from './plan';
|
||||||
|
|
||||||
|
|
@ -90,9 +91,15 @@ export const Szene4: React.FC = () => {
|
||||||
[pinoGehtBis, PINO_ZAEHL_X],
|
[pinoGehtBis, PINO_ZAEHL_X],
|
||||||
[zurueck + 10, PINO_ZAEHL_X],
|
[zurueck + 10, PINO_ZAEHL_X],
|
||||||
[zurueck + 60, NEST_X + 150],
|
[zurueck + 60, NEST_X + 150],
|
||||||
[z.bild4.ende - 20, NEST_X + 110],
|
[z.bild5.start - 20, NEST_X + 150],
|
||||||
[z.bild5.start, NEST_X],
|
[z.bild5.start, NEST_X],
|
||||||
]);
|
]);
|
||||||
|
const insNest = huepfer(f, z.bild5.start - 20, 46, 20); // Sprung ins Nest
|
||||||
|
// Anfang wie Ende von Szene 3: Pino lehnt am großen Blatt und richtet sich auf
|
||||||
|
const sitzt = kurve(f, [
|
||||||
|
[z.n1.start + 10, 1],
|
||||||
|
[z.n1.start + 34, 0],
|
||||||
|
]);
|
||||||
const pinoGeht = (f > pinoGehtVon && f < pinoGehtBis) || (f > zurueck + 10 && f < zurueck + 60);
|
const pinoGeht = (f > pinoGehtVon && f < pinoGehtBis) || (f > zurueck + 10 && f < zurueck + 60);
|
||||||
const pinoSpiegel = f > pinoGehtVon && f < pinoGehtBis; // nach rechts
|
const pinoSpiegel = f > pinoGehtVon && f < pinoGehtBis; // nach rechts
|
||||||
const imNest = f >= z.bild5.start;
|
const imNest = f >= z.bild5.start;
|
||||||
|
|
@ -130,20 +137,44 @@ export const Szene4: React.FC = () => {
|
||||||
]);
|
]);
|
||||||
const luluPose: [number, string][] = [
|
const luluPose: [number, string][] = [
|
||||||
[0, 'lulu_A5_blick-links'],
|
[0, 'lulu_A5_blick-links'],
|
||||||
[z.l1.start + 10, 'lulu_A3_lachen'],
|
|
||||||
[kitzeln + 10, 'lulu_A1_augen-zu'],
|
[kitzeln + 10, 'lulu_A1_augen-zu'],
|
||||||
[niesen + 18, 'lulu_B2_erschrocken'],
|
[niesen + 18, 'lulu_B2_erschrocken'],
|
||||||
[z.n3.start + 20, 'lulu_A3_lachen'],
|
[z.n3.start + 20, 'lulu_A3_lachen'],
|
||||||
];
|
];
|
||||||
const luluY = BODEN - 10 - strecken * 26;
|
const luluY = BODEN - 10 - strecken * 26;
|
||||||
const maul = punkt('lulu', LULU_BAUM_X, luluY, LULU_MAUL_LINKS.cx, LULU_MAUL_LINKS.cy);
|
const luluStauch = atmen(f, 3, 0.006) * (1 + 0.02 * strecken);
|
||||||
const buendel = f > amBaum + 50 && f < niesen;
|
const luluDreh = zurueckLehnen * 4;
|
||||||
// Blätter fliegen vom Ast ins Maul
|
// Punkt im Bild von Lulu, mit Drehung und Stauchung wie die Figur selbst
|
||||||
const zupfen = [0, 1, 2, 3].map((i) => {
|
const luluPunkt = (c: {cx: number; cy: number}) => {
|
||||||
const s = amBaum + 55 + i * 14;
|
const p = punkt('lulu', 0, 0, c.cx, c.cy);
|
||||||
const t = Math.min(1, Math.max(0, (f - s) / 16));
|
const dy = p.y * luluStauch;
|
||||||
return {x: maul.x - 160 + i * 50 + (maul.x - (maul.x - 160 + i * 50)) * t, y: maul.y - 120 + 120 * t, sichtbar: f > s - 20 && t < 1};
|
const a = (luluDreh * Math.PI) / 180;
|
||||||
|
return {x: LULU_BAUM_X + p.x * Math.cos(a) - dy * Math.sin(a), y: luluY + p.x * Math.sin(a) + dy * Math.cos(a)};
|
||||||
|
};
|
||||||
|
// Maul wandert mit dem Posenwechsel A5 → A1 mit
|
||||||
|
const m5 = luluPunkt(LULU_MAUL_LINKS);
|
||||||
|
const m1 = luluPunkt(LULU_MAUL_A1);
|
||||||
|
const zuA1 = kurve(f, [
|
||||||
|
[kitzeln + 10, 0],
|
||||||
|
[kitzeln + 15, 1],
|
||||||
|
]);
|
||||||
|
const maul = {x: m5.x + (m1.x - m5.x) * zuA1, y: m5.y + (m1.y - m5.y) * zuA1};
|
||||||
|
// Blätter hängen am Ast, Lulu zupft eins nach dem anderen ab; das Bündel im Maul wächst mit
|
||||||
|
const astMaul = punkt('lulu', LULU_BAUM_X, BODEN - 36, LULU_MAUL_LINKS.cx, LULU_MAUL_LINKS.cy);
|
||||||
|
const zupfen = [0, 1, 2, 3, 4].map((i) => {
|
||||||
|
const ast = {x: astMaul.x - 150 + i * 55, y: astMaul.y - 115 - (i % 2) * 35};
|
||||||
|
const los = amBaum + 50 + i * 18;
|
||||||
|
const t = Math.min(1, Math.max(0, (f - los) / 20));
|
||||||
|
const e = t * t * (3 - 2 * t);
|
||||||
|
return {
|
||||||
|
x: ast.x + (maul.x - ast.x) * e,
|
||||||
|
y: ast.y + (maul.y - ast.y) * e - Math.sin(t * Math.PI) * 30,
|
||||||
|
r: t > 0 ? 160 + t * 380 : 160 + Math.sin(f * 0.12 + i * 2) * 12,
|
||||||
|
deck: Math.min(1, Math.max(0, (f - amBaum - i * 3) / 12)),
|
||||||
|
angekommen: t >= 1,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
const imMaul = f < niesen ? zupfen.filter((b) => b.angekommen).length : 0;
|
||||||
|
|
||||||
// Kamera
|
// Kamera
|
||||||
const kam = kamFahrt(f, [
|
const kam = kamFahrt(f, [
|
||||||
|
|
@ -165,7 +196,7 @@ export const Szene4: React.FC = () => {
|
||||||
]);
|
]);
|
||||||
kam.y += ruck(f, niesen, 9, 22);
|
kam.y += ruck(f, niesen, 9, 22);
|
||||||
|
|
||||||
const lulu = <Figur pose={luluPose} x={LULU_BAUM_X} y={luluY} stauchY={atmen(f, 3, 0.006) * (1 + 0.02 * strecken)} drehung={zurueckLehnen * 4} />;
|
const lulu = <Figur pose={luluPose} x={LULU_BAUM_X} y={luluY} stauchY={luluStauch} drehung={luluDreh} />;
|
||||||
const luluBeimNest = f >= zurueck && <Figur pose="lulu_A_hals-unten" x={2030} y={BODEN - 4} drehung={schieben * 1.2} />;
|
const luluBeimNest = f >= zurueck && <Figur pose="lulu_A_hals-unten" x={2030} y={BODEN - 4} drehung={schieben * 1.2} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -173,14 +204,10 @@ export const Szene4: React.FC = () => {
|
||||||
<Kamera {...kam}>
|
<Kamera {...kam}>
|
||||||
<Ort name="garten" />
|
<Ort name="garten" />
|
||||||
{f >= amBaum && f < zurueck && lulu}
|
{f >= amBaum && f < zurueck && lulu}
|
||||||
{buendel && (
|
{f >= amBaum && f < niesen && zupfen.map((b, i) => (!b.angekommen ? <Blatt key={i} x={b.x} y={b.y} r={b.r} s={0.42} farbe={LAUB[i]} deckkraft={b.deck} /> : null))}
|
||||||
<div style={{position: 'absolute', left: 0, top: 0}}>
|
{LAUB.slice(0, imMaul).map((c, i) => (
|
||||||
{LAUB.slice(0, 5).map((c, i) => (
|
<Blatt key={`m${i}`} x={maul.x - 4 + (i - 2) * 9} y={maul.y + 12 + Math.abs(i - 2) * 4} r={(i - 2) * 30 + 180} s={0.42} farbe={c} />
|
||||||
<Blatt key={i} x={maul.x - 6 + (i - 2) * 9} y={maul.y + 14 + Math.abs(i - 2) * 4} r={(i - 2) * 30 + 180} s={0.42} farbe={c} />
|
))}
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{zupfen.map((b, i) => (b.sichtbar ? <Blatt key={i} x={b.x} y={b.y} r={f * 8 + i * 70} s={0.42} farbe={LAUB[i]} /> : null))}
|
|
||||||
|
|
||||||
{/* Reihe aus fünf Blättern vor dem Holzstapel */}
|
{/* Reihe aus fünf Blättern vor dem Holzstapel */}
|
||||||
{f < zurueck + 40 &&
|
{f < zurueck + 40 &&
|
||||||
|
|
@ -195,6 +222,8 @@ export const Szene4: React.FC = () => {
|
||||||
) : (
|
) : (
|
||||||
<Figur pose={noaPose} x={noaX} y={BODEN} stauchY={atmen(f, 2)} />
|
<Figur pose={noaPose} x={noaX} y={BODEN} stauchY={atmen(f, 2)} />
|
||||||
)}
|
)}
|
||||||
|
{/* das große Blatt aus Szene 3 bleibt liegen */}
|
||||||
|
{f < zurueck + 40 && <Blatt x={GROSSES_BLATT_X} y={BODEN - 8} r={88} s={2.6} farbe="#c8642c" deckkraft={f > zurueck ? 1 - (f - zurueck) / 40 : 1} />}
|
||||||
{imNest ? (
|
{imNest ? (
|
||||||
<div style={{position: 'absolute', inset: 0, clipPath: `inset(0 0 ${1080 - BODEN - 4}px 0)`}}>
|
<div style={{position: 'absolute', inset: 0, clipPath: `inset(0 0 ${1080 - BODEN - 4}px 0)`}}>
|
||||||
<Figur pose={pinoPose} x={NEST_X} y={pinoImNestY} schatten={false} />
|
<Figur pose={pinoPose} x={NEST_X} y={pinoImNestY} schatten={false} />
|
||||||
|
|
@ -205,8 +234,9 @@ export const Szene4: React.FC = () => {
|
||||||
<Figur
|
<Figur
|
||||||
pose={pinoPose}
|
pose={pinoPose}
|
||||||
x={pinoX}
|
x={pinoX}
|
||||||
y={BODEN + zaehlHuepfer + huepfer(f, niesen + 2, 30, 12)}
|
y={BODEN - 6 * sitzt + zaehlHuepfer + huepfer(f, niesen + 2, 30, 12) + insNest}
|
||||||
stauchY={atmen(f, 1) * hopfStauch(f, niesen + 2)}
|
stauchY={atmen(f, 1) * hopfStauch(f, niesen + 2) * hopfStauch(f, z.bild5.start - 20, 20)}
|
||||||
|
drehung={-9 * sitzt}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Nest x={NEST_X} y={BODEN} seite="vorne" voll={f < zurueck ? 0 : nestVoll} />
|
<Nest x={NEST_X} y={BODEN} seite="vorne" voll={f < zurueck ? 0 : nestVoll} />
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import {kurve} from '../bewegung';
|
||||||
import {ClipFigur, Figur, Kamera} from '../baukasten/figur';
|
import {ClipFigur, Figur, Kamera} from '../baukasten/figur';
|
||||||
import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
|
import {Blende, Vignette, atmen, huepfer, kamFahrt} from '../baukasten/helfer';
|
||||||
import {Funkeln} from '../baukasten/natur';
|
import {Funkeln} from '../baukasten/natur';
|
||||||
import {KALENDER_TUER1, KalenderMalen, Ort} from '../baukasten/orte';
|
import {KALENDER_TUER1, KalenderAufTisch, KalenderMalen, Ort} from '../baukasten/orte';
|
||||||
import {Untertitel} from '../baukasten/untertitel';
|
import {Untertitel} from '../baukasten/untertitel';
|
||||||
import {plane} from './plan';
|
import {plane} from './plan';
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ const LULU_X6 = 1440;
|
||||||
|
|
||||||
export const S6 = plane('s6', [
|
export const S6 = plane('s6', [
|
||||||
{id: 'bild0', dauer: 3.0},
|
{id: 'bild0', dauer: 3.0},
|
||||||
{id: 'malen', dauer: 4.0},
|
{id: 'malen', dauer: 5.5},
|
||||||
{id: 'l1', wer: 'LULU', text: 'Was malst du da, Noa?'},
|
{id: 'l1', wer: 'LULU', text: 'Was malst du da, Noa?'},
|
||||||
{id: 'n1', wer: 'NOA', text: 'Einen Kalender! Mit 24 Türchen.'},
|
{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: 'n2', wer: 'NOA', text: 'Wir öffnen jeden Tag eins. Und hinter jedem Türchen steckt etwas, das Pino wach hält.'},
|
||||||
|
|
@ -34,10 +34,14 @@ export const Szene6: React.FC = () => {
|
||||||
const f = useCurrentFrame();
|
const f = useCurrentFrame();
|
||||||
const {z, dauer} = S6;
|
const {z, dauer} = S6;
|
||||||
|
|
||||||
// Noa malt: Blick von oben aufs Blatt, während „malen“ und während sie antwortet (n1)
|
// 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, [
|
const malP = kurve(f, [
|
||||||
[z.malen.start, 0],
|
[z.malen.start, 0],
|
||||||
[z.n1.ende, 1],
|
[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 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 malt = f < z.n1.ende;
|
||||||
|
|
@ -60,7 +64,8 @@ export const Szene6: React.FC = () => {
|
||||||
const kam = kamFahrt(f, [
|
const kam = kamFahrt(f, [
|
||||||
[0, 960, 540, 1.0],
|
[0, 960, 540, 1.0],
|
||||||
[z.bild0.ende, 1060, 560, 1.15],
|
[z.bild0.ende, 1060, 560, 1.15],
|
||||||
[z.n1.start, 900, 640, 1.45],
|
[z.l1.start, 1080, 640, 1.5],
|
||||||
|
[z.n1.ende, 1060, 650, 1.5],
|
||||||
[z.p1.start, 980, 650, 1.6],
|
[z.p1.start, 980, 650, 1.6],
|
||||||
[z.n4.ende, 960, 640, 1.5],
|
[z.n4.ende, 960, 640, 1.5],
|
||||||
[sprung + 10, 1050, 700, 2.0],
|
[sprung + 10, 1050, 700, 2.0],
|
||||||
|
|
@ -144,6 +149,7 @@ export const Szene6: React.FC = () => {
|
||||||
schatten={false}
|
schatten={false}
|
||||||
/>
|
/>
|
||||||
<Ort name="zimmer_tisch" />
|
<Ort name="zimmer_tisch" />
|
||||||
|
{f >= z.malen.start && <KalenderAufTisch p={malP} />}
|
||||||
{imSprung ? (
|
{imSprung ? (
|
||||||
<ClipFigur name="pino_C3_freudensprung" start={sprung} tempo={1.4} x={PINO_X6} y={TISCH_Y} hoehe={N * 0.4} />
|
<ClipFigur name="pino_C3_freudensprung" start={sprung} tempo={1.4} x={PINO_X6} y={TISCH_Y} hoehe={N * 0.4} />
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||