Folge 1, Szene 2, Rückmeldung 2: alter Apfelbaum wie bei Higgsfield (knorriger Stamm, Gabel, kahle Äste, Zweig zum Apfel), Noa geht zügiger, Hocke ohne Clip als weiche Überblendung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
132e969d03
commit
3c5620ef6e
4 changed files with 55 additions and 11 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 83 KiB |
|
|
@ -221,6 +221,50 @@ export const GartenSVG: React.FC<{nacht?: boolean}> = ({nacht = false}) => (
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Folge 1: alter Apfelbaum wie in den Higgsfield-Bildern – knorriger Stamm mit
|
||||||
|
// Wurzelansatz und Rinde, weit ausladende kahle Äste, nur noch wenige Blätter.
|
||||||
|
// Ein Zweig führt zum Apfel (Apfel selbst ist ein eigenes Teil, siehe APFEL in folge01/szene2).
|
||||||
|
const AlterBaum: React.FC<{x: number; y: number; s?: number; abend?: boolean; apfel?: [number, number]}> = ({x, y, s = 1, abend, apfel}) => {
|
||||||
|
const stamm = abend ? '#5e4a3c' : '#7a6452';
|
||||||
|
const ast = abend ? '#56443a' : '#6b5646';
|
||||||
|
const rinde = abend ? '#3e3028' : '#4f3e32';
|
||||||
|
return (
|
||||||
|
<g transform={`translate(${x} ${y}) scale(${s})`}>
|
||||||
|
<Ast x={-138} y={-478} w={-128} l={175} d={20} tiefe={5} farbe={ast} seed="ba" />
|
||||||
|
<Ast x={-138} y={-478} w={-70} l={160} d={16} tiefe={4} farbe={ast} seed="bf" />
|
||||||
|
<Ast x={74} y={-512} w={-62} l={185} d={20} tiefe={5} farbe={ast} seed="bc" />
|
||||||
|
<Ast x={74} y={-512} w={-20} l={150} d={14} tiefe={4} farbe={ast} seed="bg" />
|
||||||
|
<Ast x={-20} y={-352} w={-96} l={170} d={16} tiefe={4} farbe={ast} seed="bb" />
|
||||||
|
<Ast x={-48} y={-262} w={-168} l={160} d={16} tiefe={4} farbe={ast} seed="bd" />
|
||||||
|
<Ast x={36} y={-250} w={-12} l={170} d={16} tiefe={4} farbe={ast} seed="be" />
|
||||||
|
{apfel && (
|
||||||
|
<g fill="none" stroke={ast} strokeLinecap="round">
|
||||||
|
<path d={`M 70 -500 Q ${apfel[0] * 0.5} ${apfel[1] * 0.85}, ${apfel[0] * 0.85} ${apfel[1] + 26}`} strokeWidth={11} />
|
||||||
|
<path d={`M ${apfel[0] * 0.85} ${apfel[1] + 26} Q ${apfel[0] * 0.95} ${apfel[1] - 8}, ${apfel[0]} ${apfel[1]}`} strokeWidth={4} />
|
||||||
|
</g>
|
||||||
|
)}
|
||||||
|
{/* Stamm mit Wurzelansatz, gabelt sich in zwei dicke Äste */}
|
||||||
|
<path
|
||||||
|
d="M -96 6 C -70 -2, -50 -16, -46 -60 C -40 -150, -60 -230, -50 -300 C -70 -360, -110 -420, -150 -470 L -126 -490 C -90 -440, -50 -392, -20 -352 C 0 -400, 30 -460, 60 -522 L 90 -508 C 62 -440, 40 -372, 34 -300 C 30 -200, 34 -120, 44 -70 C 50 -28, 70 -6, 104 6 C 60 10, 20 2, 0 8 C -24 2, -60 10, -96 6 Z"
|
||||||
|
fill={stamm}
|
||||||
|
filter="url(#aq)"
|
||||||
|
/>
|
||||||
|
{/* Rinde */}
|
||||||
|
{[-24, -8, 8, 22].map((dx, i) => (
|
||||||
|
<path key={i} d={`M ${dx} -20 C ${dx - 8} -110, ${dx + 8} -200, ${dx - 4} -${250 + i * 12}`} stroke={rinde} strokeWidth={3} fill="none" opacity={0.55} strokeLinecap="round" />
|
||||||
|
))}
|
||||||
|
<path d="M -60 -6 C -40 -30, -36 -40, -38 -70 M 62 -4 C 46 -24, 40 -40, 40 -66" stroke={rinde} strokeWidth={3} fill="none" opacity={0.5} />
|
||||||
|
<ellipse cx={-6} cy={-170} rx={9} ry={14} fill={rinde} opacity={0.5} />
|
||||||
|
{/* die letzten Blätter */}
|
||||||
|
{new Array(14).fill(0).map((_, i) => {
|
||||||
|
const bx = -300 + random('ab' + i) * 600;
|
||||||
|
const by = -720 + random('aby' + i) * 330;
|
||||||
|
return <ellipse key={i} cx={bx} cy={by} rx={10} ry={6} transform={`rotate(${random('abr' + i) * 180} ${bx} ${by})`} fill={['#c8642c', '#d99a2b', '#a8452a'][i % 3]} />;
|
||||||
|
})}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Folge 1: Noas Garten im goldenen Herbst (Morgen) bzw. im Abendlicht.
|
// Folge 1: Noas Garten im goldenen Herbst (Morgen) bzw. im Abendlicht.
|
||||||
// Ohne Holzstapel (der kommt erst in Folge 2); Apfel, Blume und Laubhaufen sind eigene Teile.
|
// Ohne Holzstapel (der kommt erst in Folge 2); Apfel, Blume und Laubhaufen sind eigene Teile.
|
||||||
export const GartenHerbstSVG: React.FC<{abend?: boolean}> = ({abend = false}) => (
|
export const GartenHerbstSVG: React.FC<{abend?: boolean}> = ({abend = false}) => (
|
||||||
|
|
@ -271,7 +315,7 @@ export const GartenHerbstSVG: React.FC<{abend?: boolean}> = ({abend = false}) =>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</g>
|
</g>
|
||||||
<Apfelbaum x={330} y={900} s={1.05} farbe={abend ? '#5e4232' : '#6e5038'} krone={abend ? 'abend' : 'morgen'} />
|
<AlterBaum x={340} y={905} s={0.95} abend={abend} apfel={[232, -770]} />
|
||||||
<Korn staerke={0.18} />
|
<Korn staerke={0.18} />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {useCurrentFrame} from 'remotion';
|
import {useCurrentFrame} from 'remotion';
|
||||||
import {kurve} from '../bewegung';
|
import {kurve} from '../bewegung';
|
||||||
import {ClipFigur, Figur, Geher, Kamera, NOA_HOCKE_FRAMES, NoaHocke} from '../baukasten/figur';
|
import {ClipFigur, Figur, Geher, Kamera} from '../baukasten/figur';
|
||||||
import {Blende, Vignette, atmen, hopfStauch, huepfer, kamFahrt, ruck} from '../baukasten/helfer';
|
import {Blende, Vignette, atmen, hopfStauch, huepfer, kamFahrt, ruck} from '../baukasten/helfer';
|
||||||
import {Apfel, Blaetterregen, Blaetterwind, Blume, Laubhaufen} from '../baukasten/natur';
|
import {Apfel, Blaetterregen, Blaetterwind, Blume, Laubhaufen} from '../baukasten/natur';
|
||||||
import {BODEN, Ort} from '../baukasten/orte';
|
import {BODEN, Ort} from '../baukasten/orte';
|
||||||
|
|
@ -44,7 +44,7 @@ export const Szene2: React.FC = () => {
|
||||||
const {z, dauer} = S2;
|
const {z, dauer} = S2;
|
||||||
|
|
||||||
// Noa kommt von links, springt bei „Hui!“ mitten in den Haufen und hüpft wieder heraus
|
// Noa kommt von links, springt bei „Hui!“ mitten in den Haufen und hüpft wieder heraus
|
||||||
const noaAn = z.e3.ende - 10;
|
const noaAn = z.bild0.start + 10 + 165; // zügig, ca. 5,5 s
|
||||||
const sprung = z.n1.start + 4;
|
const sprung = z.n1.start + 4;
|
||||||
const SPRUNG_DAUER = 22;
|
const SPRUNG_DAUER = 22;
|
||||||
const landung = sprung + SPRUNG_DAUER;
|
const landung = sprung + SPRUNG_DAUER;
|
||||||
|
|
@ -71,18 +71,20 @@ export const Szene2: React.FC = () => {
|
||||||
[schreck, 'noa_B2_erschrocken'],
|
[schreck, 'noa_B2_erschrocken'],
|
||||||
[z.n2.start + 6, 'noa_A4_staunen'],
|
[z.n2.start + 6, 'noa_A4_staunen'],
|
||||||
[z.e6.start, 'noa_A6_blick-rechts'],
|
[z.e6.start, 'noa_A6_blick-rechts'],
|
||||||
|
[hocke, 'noa_B_hocken'],
|
||||||
[aufstehen, 'noa_A3_lachen'],
|
[aufstehen, 'noa_A3_lachen'],
|
||||||
[z.p2.start + 10, 'noa_A6_blick-rechts'],
|
[z.p2.start + 10, 'noa_A6_blick-rechts'],
|
||||||
];
|
];
|
||||||
// Hocke: Clip „hinsetzen“ bis zur Hocke, zum Aufstehen rückwärts
|
// Hocke: Standbilder weich überblenden, dabei kurz absinken bzw. sich strecken
|
||||||
const inHocke = f >= hocke && f < aufstehen + NOA_HOCKE_FRAMES;
|
const HOCKE_BLENDE = 14;
|
||||||
const hockeStart = f < aufstehen ? hocke : aufstehen;
|
const wechsel = (t: number) => (f >= t && f < t + HOCKE_BLENDE ? Math.sin(((f - t) / HOCKE_BLENDE) * Math.PI) : 0);
|
||||||
|
const hockeStauch = 1 - 0.05 * wechsel(hocke) + 0.03 * wechsel(aufstehen);
|
||||||
const noaY =
|
const noaY =
|
||||||
BODEN +
|
BODEN +
|
||||||
sprungY +
|
sprungY +
|
||||||
huepfer(f, raus, 60, 16) +
|
huepfer(f, raus, 60, 16) +
|
||||||
ruck(f, schreck, 3) +
|
ruck(f, schreck, 3) +
|
||||||
huepfer(f, aufstehen + NOA_HOCKE_FRAMES + 4, 14, 10);
|
huepfer(f, aufstehen + HOCKE_BLENDE + 4, 14, 10);
|
||||||
|
|
||||||
// Laubhaufen: wird bei der Landung gestaucht, später raschelt er
|
// Laubhaufen: wird bei der Landung gestaucht, später raschelt er
|
||||||
const flach = kurve(f, [
|
const flach = kurve(f, [
|
||||||
|
|
@ -151,11 +153,9 @@ export const Szene2: React.FC = () => {
|
||||||
{imHaufen && <Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2) * hopfStauch(f, landung)} schatten={false} />}
|
{imHaufen && <Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2) * hopfStauch(f, landung)} schatten={false} />}
|
||||||
<Laubhaufen x={HAUFEN_X} y={BODEN + 6} wackeln={wackeln} flach={flach} />
|
<Laubhaufen x={HAUFEN_X} y={BODEN + 6} wackeln={wackeln} flach={flach} />
|
||||||
{imHaufen ? null : noaGeht ? (
|
{imHaufen ? null : noaGeht ? (
|
||||||
<Geher figur="noa" spiegeln x={noaX} y={BODEN} />
|
<Geher figur="noa" spiegeln x={noaX} y={BODEN} tempo={1.5} />
|
||||||
) : inHocke ? (
|
|
||||||
<NoaHocke start={hockeStart} auf={f >= aufstehen} x={noaX} y={BODEN} />
|
|
||||||
) : (
|
) : (
|
||||||
<Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2) * hopfStauch(f, landung)} />
|
<Figur pose={noaPose} x={noaX} y={noaY} stauchY={atmen(f, 2) * hopfStauch(f, landung) * hockeStauch} blende={f >= hocke ? HOCKE_BLENDE : 5} />
|
||||||
)}
|
)}
|
||||||
<Blaetterregen start={landung - 2} x0={HAUFEN_X - 60} y0={BODEN - 60} boden={BODEN - 10} anzahl={28} aus={z.e4.start} />
|
<Blaetterregen start={landung - 2} x0={HAUFEN_X - 60} y0={BODEN - 60} boden={BODEN - 10} anzahl={28} aus={z.e4.start} />
|
||||||
</Kamera>
|
</Kamera>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue