From f303ec8d7aece827e41fc3c14c7a37afbe2ee6a2 Mon Sep 17 00:00:00 2001 From: Lara Date: Fri, 6 Nov 2026 08:15:05 +0000 Subject: [PATCH] =?UTF-8?q?Folge=208=20nach=20R=C3=BCckmeldung:=20Fenster?= =?UTF-8?q?=20ohne=20Papa-Umriss=20(warmes=20Zimmer),=20Schattenspiel=20mi?= =?UTF-8?q?t=20Noas=20Hand=20vor=20der=20Laterne=20(Hand=20und=20Schatten?= =?UTF-8?q?=20aus=20derselben=20Form,=20Schatten=20projiziert),=20alle=20a?= =?UTF-8?q?tmen/wiegen=20sich=20an=20der=20Wand,=20Haken=20nur=20in=20Szen?= =?UTF-8?q?e=208=20mit=20Schnur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- remotion/src/folge08/szene3.tsx | 4 +- remotion/src/folge08/szene7.tsx | 38 +++++++--- remotion/src/folge08/szene8.tsx | 6 +- remotion/src/folge08/teile.tsx | 118 +++++++++++++++++++++----------- remotion/src/folge08/wand.tsx | 22 +++--- 5 files changed, 128 insertions(+), 60 deletions(-) diff --git a/remotion/src/folge08/szene3.tsx b/remotion/src/folge08/szene3.tsx index e69f8a7..9acf0dd 100644 --- a/remotion/src/folge08/szene3.tsx +++ b/remotion/src/folge08/szene3.tsx @@ -9,7 +9,7 @@ import {Untertitel} from '../baukasten/untertitel'; import {plane} from './plan'; import {Abenddunkel, GartenAbend, Laterne, laterneInNoasHand} from './teile'; -// Szene 3: Es wird dunkel. Abendgarten, rechts die Hauswand, Papa winkt im Fenster. +// Szene 3: Es wird dunkel. Abendgarten, rechts die Hauswand mit erleuchtetem Fenster. // Noa knipst das Lämpchen an (kein Feuer) und singt den Laternenvers; die Laterne pendelt sanft. // Pino tippelt zu ihr (baukasten/gang.ts, Füße rutschen nicht). Lulu steht schon an der Hauswand – // sie geht nicht durchs Bild, weil ihr Geh-Clip kein echtes Gehen ist. @@ -62,7 +62,7 @@ export const Szene3: React.FC = () => { return ( <> - + { const f = useCurrentFrame(); @@ -30,12 +38,16 @@ export const Szene7: React.FC = () => { const hase = interpolate(f, [z.bild0.start + 6, z.bild0.ende, z.hals.start, z.hals.start + 10], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); const igel = interpolate(f, [z.igel.start, z.igel.start + 12, dauer - 20, dauer - 6], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); const strecken = interpolate(f, [z.hals.start, z.hals.start + 20, z.hals.ende - 10, z.hals.ende + 6], [1, 1.12, 1.12, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}); + const wackelnHase = Math.sin(f * 0.25); + const wackelnIgel = Math.sin(f * 0.3); + // die Hand wippt leicht; der Schatten wippt K-mal so weit mit + const hand = {x: HAND.x + Math.sin(f * 0.07) * 4, y: HAND.y + Math.sin(f * 0.09) * 5}; const kam = kamFahrt(f, [ - [0, 1000, 520, 1.0], - [z.n1.start, 1000, 470, 1.12], - [z.hals.start, 1100, 500, 0.98], - [z.igel.start, 1000, 480, 1.1], - [dauer, 1000, 500, 1.06], + [0, 920, 600, 1.2], + [z.n1.start, 920, 620, 1.28], + [z.hals.start, 1060, 520, 0.98], + [z.igel.start, 920, 610, 1.25], + [dauer, 920, 620, 1.22], ]); return ( <> @@ -43,13 +55,19 @@ export const Szene7: React.FC = () => { f={f} kam={kam} laterne={{inHand: false, licht: 1, x: LATERNE.x, y: LATERNE.y}} - noa={{pose: [[0, 'noa_B_hocken'], [z.igel.start, 'noa_B_hocken']], x: PLATZ.noa + 140}} + noa={{pose: 'noa_B_hocken', x: NOA_X}} pino={{pose: [[0, 'pino_A4_staunen'], [z.p1.start, 'pino_A3_lachen']], x: LATERNE.x - 230}} lulu={{pose: 'lulu_A3_lachen', stauchY: strecken}} wandExtra={ <> - - + + + + } + vorne={ + <> + {hase > 0 && } + {igel > 0 && } } /> diff --git a/remotion/src/folge08/szene8.tsx b/remotion/src/folge08/szene8.tsx index 9a8040b..2077a1e 100644 --- a/remotion/src/folge08/szene8.tsx +++ b/remotion/src/folge08/szene8.tsx @@ -42,9 +42,13 @@ export const Szene8: React.FC = () => { return ( <> - + {/* warmer Lichtschein der Laterne fällt auf den Laubhaufen */}
+ {/* Schnur vom Haken zur Laterne */} + + + diff --git a/remotion/src/folge08/teile.tsx b/remotion/src/folge08/teile.tsx index 9e1c3d5..0369e02 100644 --- a/remotion/src/folge08/teile.tsx +++ b/remotion/src/folge08/teile.tsx @@ -12,7 +12,7 @@ export const WAND = {x0: 1060, x1: 1980, oben: 170, unten: BODEN - 30}; export const FENSTER = {x: 1180, y: 280, b: 230, h: 210}; // Abendgarten in der „blauen Stunde“: Nachtgarten aufgehellt, damit es freundlich und nicht unheimlich wirkt -export const GartenAbend: React.FC<{wandVoll?: boolean; papaWinkt?: number}> = ({wandVoll = false, papaWinkt = 0}) => { +export const GartenAbend: React.FC<{wandVoll?: boolean; haken?: boolean}> = ({wandVoll = false, haken = false}) => { const x0 = wandVoll ? -60 : WAND.x0; const oben = wandVoll ? 70 : WAND.oben; return ( @@ -39,25 +39,22 @@ export const GartenAbend: React.FC<{wandVoll?: boolean; papaWinkt?: number}> = ( {!wandVoll && } {!wandVoll && ( <> - {/* erleuchtetes Fenster mit Papa als Umriss */} + {/* erleuchtetes Fenster: warmes Zimmer mit Vorhängen und Lampe (keine Figur – wirkte unecht) */} - - - - - {/* winkender Arm */} - - - - - - - + + + + + + + + + )} - {/* Haken für die Laterne (Szene 8) */} - + {/* Haken mit Schnur für die Laterne (nur Szene 8) */} + {haken && } ); @@ -178,29 +175,72 @@ export const WandSchatten: React.FC<{
); -// Hand-Schatten an der Wand: Hase (zwei Ohren) und Igel (Faust mit gespreizten Fingern) -export const HandSchatten: React.FC<{art: 'hase' | 'igel'; x: number; y: number; s?: number; deckkraft?: number; wackeln?: number}> = ({art, x, y, s = 1, deckkraft = 0.45, wackeln = 0}) => ( - - {art === 'hase' ? ( - - - - - - - - ) : ( - - - {[-70, -35, 0, 35, 70].map((dx, i) => ( - - ))} - - - - )} - -); +// Hand-Schatten: Noa formt vor der Laterne mit der Hand einen Hasen oder einen Igel. Hand und Schatten +// entstehen aus derselben Form – wackeln die Ohren, wackelt der Schatten genau mit. Der Schatten ist die +// Hand, vom Licht aus an die Wand projiziert: Mitte = Licht + (Hand − Licht) · k, Größe · k. +const HandForm: React.FC<{art: 'hase' | 'igel'; wackeln: number; farbe: string; rand?: string}> = ({art, wackeln, farbe, rand}) => { + const strich = rand ? {stroke: rand, strokeWidth: 5} : {}; + return art === 'hase' ? ( + + + + + + + + ) : ( + + + {[-70, -35, 0, 35, 70].map((dx, i) => ( + + ))} + + + + ); +}; + +const HANDBOX = 400; +export const HandSchatten: React.FC<{art: 'hase' | 'igel'; hand: {x: number; y: number}; licht: {x: number; y: number}; s: number; k: number; deckkraft?: number; wackeln?: number}> = ({ + art, + hand, + licht, + s, + k, + deckkraft = 0.45, + wackeln = 0, +}) => { + const x = licht.x + (hand.x - licht.x) * k; + const y = licht.y + (hand.y - licht.y) * k; + return ( + + + + ); +}; + +// Noas Arm (Jackenärmel) von der Schulter bis zur Hand, die Hand formt Hase oder Igel +export const NoasHand: React.FC<{art: 'hase' | 'igel'; schulter: {x: number; y: number}; hand: {x: number; y: number}; s: number; wackeln?: number; deckkraft?: number}> = ({ + art, + schulter, + hand, + s, + wackeln = 0, + deckkraft = 1, +}) => { + const handgelenk = {x: hand.x - 6 * s * 10, y: hand.y + 150 * s}; + return ( +
+ + + + + + + +
+ ); +}; // Wo die Laterne in der Pose noa_A_laterne hängt, und wie groß unsere Laterne sein muss, um die orange // Laterne des Bildes ganz abzudecken (gemessen: 131 × 134 Bildpunkte, Mitte bei 73/423 im Bild, Bild bei 339/156) diff --git a/remotion/src/folge08/wand.tsx b/remotion/src/folge08/wand.tsx index 6e40bf2..58a785c 100644 --- a/remotion/src/folge08/wand.tsx +++ b/remotion/src/folge08/wand.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {ClipFigur, Figur, Kamera, type Posenfolge} from '../baukasten/figur'; import type {Gang} from '../baukasten/gang'; -import {Vignette} from '../baukasten/helfer'; +import {Vignette, atmen} from '../baukasten/helfer'; import {BODEN} from '../baukasten/orte'; import {Abenddunkel, GartenAbend, Laterne, WAND_VOLL, WandSchatten, laterneInNoasHand} from './teile'; @@ -18,11 +18,12 @@ export type Buehne = { noa: {pose: string | Posenfolge; x?: number}; pino: {pose: string | Posenfolge; x: number; gang?: Gang; drehung?: number; y?: number; k?: number; versatz?: number}; lulu: {pose: string | Posenfolge; x?: number; hell?: number; drehung?: number; stauchY?: number; k?: number}; - wandExtra?: React.ReactNode; // z. B. Hand-Schatten + wandExtra?: React.ReactNode; // z. B. Hand-Schatten (an der Wand, hinter den Figuren) + vorne?: React.ReactNode; // z. B. Noas Hand vor der Laterne f: number; }; -export const Wandszene: React.FC = ({kam, laterne, noa, pino, lulu, wandExtra, f}) => { +export const Wandszene: React.FC = ({kam, laterne, noa, pino, lulu, wandExtra, vorne, f}) => { const noaX = noa.x ?? PLATZ.noa; const luluX = lulu.x ?? PLATZ.lulu; const hand = laterneInNoasHand(noaX); @@ -32,16 +33,20 @@ export const Wandszene: React.FC = ({kam, laterne, noa, pino, lulu, wand const kPino = pino.k ?? 1 + 220 / Math.max(80, Math.abs(pino.x - lat.x)); const hell = lulu.hell ?? 1; const pinoGeht = pino.gang?.geht(f); + // Niemand steht ganz still: alle atmen, Lulu wiegt sich leicht – die Schatten machen es mit + const luluDreh = lulu.drehung ?? Math.sin(f * 0.035) * 1.3; + const luluStauch = (lulu.stauchY ?? 1) * atmen(f, 3, 0.006); + const pinoStauch = atmen(f, 1, 0.015); return ( <> {/* Schatten an der Wand (hinter den Figuren) */} - - + + {wandExtra} - - + + {laterne.inHand ? ( ) : ( @@ -50,8 +55,9 @@ export const Wandszene: React.FC = ({kam, laterne, noa, pino, lulu, wand {pinoGeht && pino.gang ? ( ) : ( - + )} + {vorne}