Drachenschnur als Linie in Remotion für noa_A_drachenschnur
- baukasten/drachenschnur.tsx: <Drachenschnur von nach> zeichnet die Schnur als Kurve mit Durchhang und leichtem Flattern im Wind (durchhang, wind, staerke, deckkraft einstellbar); spulenPunkt(x, y, hoehe, spiegeln) liefert den Ansatz an Noas Spule mit denselben Lage-Werten wie <Figur> - Ansatzpunkt in der Leinwand (770, 405) am Rohbild gemessen: die Schnur kommt oben aus der Wicklung - Prüfszene DrachenschnurTest (Noa normal und gespiegelt/größer, Platzhalter-Drachen pendelt) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d88a3bfd8f
commit
21324b0ef6
4 changed files with 99 additions and 1 deletions
|
|
@ -46,7 +46,7 @@ unter `figuren/bibliothek/`. Die **Clips** (MP4) sind nicht im Git (siehe
|
|||
| noa_A_arme-hoch | beide Arme hoch | 1 | 1,5 | |
|
||||
| noa_A_klatschen | klatscht, Fäustlinge vor der Brust (02.11.2026, Nano Banana 2 aus noa_ref_stehend, für das Lied) | 1 | 1,5 | ohne rembg freigestellt |
|
||||
| noa_A_laterne | Laterne in rechter Hand | 2 | 3 | 1. Versuch ohne Laterne; 2. gespiegelt; Laterne ragt seitlich weit heraus |
|
||||
| noa_A_drachenschnur | steht leicht nach rechts gedreht, hält eine Drachenspule mit beiden Fäustlingen, schaut nach oben rechts (07.11.2026, Nano Banana Pro 1k aus noa_ref_stehend, für „Lulu und der Drachen“) | 2 | 4 | 1. Versuch mit losem Schnurende am Boden; Schnur beim Freistellen entfernt, wird in Remotion als Linie ab der Spule (rechtes Ende ca. x 790, y 400 in der Leinwand) gezeichnet; ohne rembg freigestellt |
|
||||
| noa_A_drachenschnur | steht leicht nach rechts gedreht, hält eine Drachenspule mit beiden Fäustlingen, schaut nach oben rechts (07.11.2026, Nano Banana Pro 1k aus noa_ref_stehend, für „Lulu und der Drachen“) | 2 | 4 | 1. Versuch mit losem Schnurende am Boden; Schnur beim Freistellen entfernt, wird in Remotion als Linie gezeichnet: `Drachenschnur` + `spulenPunkt` in `remotion/src/baukasten/drachenschnur.tsx` (Ansatz x 770, y 405 in der Leinwand), Prüfszene `DrachenschnurTest`; ohne rembg freigestellt |
|
||||
| noa_A_haende-oben | steht frontal, Fäustlinge über dem Kopf, fröhlich-stolz (07.11.2026, Nano Banana Pro 1k aus noa_ref_stehend) | 1 | 2 | Arme eher jubelnd auseinander statt dicht beieinander, Zöpfe kaum sichtbar – so abgenommen; ohne rembg freigestellt |
|
||||
| noa_B1_traurig | traurig | 2 | 1,5 | 1. Versuch abgebrochen, erstattet |
|
||||
| noa_B2_erschrocken | kurz erschrocken | 1 | 1,5 | |
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {HintergrundAbend, PapierStruktur, VordergrundAbend} from './szenen/Hinte
|
|||
import {LaterneTest} from './szenen/LaterneTest';
|
||||
import {GANGTEST_DAUER, GangTest} from './szenen/GangTest';
|
||||
import {VerformTest} from './szenen/VerformTest';
|
||||
import {DrachenschnurTest} from './szenen/DrachenschnurTest';
|
||||
import {FolgenKompositionen} from './baukasten/folge';
|
||||
import {NEST_BILD} from './baukasten/natur';
|
||||
import {NestStill, ORTE, OrtStill} from './baukasten/orte';
|
||||
|
|
@ -28,6 +29,7 @@ export const Root: React.FC = () => (
|
|||
<Composition id="GangTest" component={GangTest} durationInFrames={GANGTEST_DAUER} {...BILD} />
|
||||
<Composition id="LaterneTest" component={LaterneTest} durationInFrames={420} {...BILD} />
|
||||
<Composition id="VerformTest" component={VerformTest} durationInFrames={240} {...BILD} />
|
||||
<Composition id="DrachenschnurTest" component={DrachenschnurTest} durationInFrames={150} {...BILD} />
|
||||
<Composition id="HintergrundAbend" component={HintergrundAbend} durationInFrames={1} {...BILD} />
|
||||
<Composition id="VordergrundAbend" component={VordergrundAbend} durationInFrames={1} {...BILD} />
|
||||
<Composition id="PapierStruktur" component={PapierStruktur} durationInFrames={1} {...BILD} />
|
||||
|
|
|
|||
64
remotion/src/baukasten/drachenschnur.tsx
Normal file
64
remotion/src/baukasten/drachenschnur.tsx
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import React from 'react';
|
||||
import {useCurrentFrame} from 'remotion';
|
||||
import {GROESSE, NOA_HOEHE} from './figur';
|
||||
import {punkt} from './helfer';
|
||||
|
||||
// Drachenschnur für die Pose noa_A_drachenschnur („Lulu und der Drachen“).
|
||||
// Im Bild hält Noa nur die Holzspule; die gemalte Schnur ist beim Freistellen
|
||||
// entfernt worden. Hier wird sie als Linie von der Spule bis zum Drachen gezogen,
|
||||
// mit leichtem Durchhang und etwas Wind.
|
||||
|
||||
// Austritt der Schnur aus der Wicklung (oben, vor der rechten Scheibe), in der Bild-Leinwand
|
||||
// von noa_A_drachenschnur (1376 × 768), gemessen am Rohbild.
|
||||
export const NOA_SPULE = {cx: 770, cy: 405};
|
||||
|
||||
// Bildschirmpunkt der Spule für eine Noa mit denselben Lage-Werten wie <Figur>.
|
||||
export const spulenPunkt = (x: number, y: number, hoehe = NOA_HOEHE * GROESSE.noa, spiegeln = false) =>
|
||||
punkt('noa', x, y, NOA_SPULE.cx, NOA_SPULE.cy, hoehe, spiegeln);
|
||||
|
||||
type SchnurProps = {
|
||||
von: {x: number; y: number}; // meist spulenPunkt(...)
|
||||
nach: {x: number; y: number}; // Haltepunkt am Drachen
|
||||
durchhang?: number; // Anteil der Schnurlänge, um den die Mitte nach unten hängt (straff = 0.02, locker = 0.12)
|
||||
wind?: number; // Stärke des Flatterns in px
|
||||
staerke?: number; // Linienbreite in px
|
||||
farbe?: string;
|
||||
deckkraft?: number;
|
||||
frame?: number;
|
||||
};
|
||||
|
||||
export const Drachenschnur: React.FC<SchnurProps> = ({
|
||||
von,
|
||||
nach,
|
||||
durchhang = 0.06,
|
||||
wind = 6,
|
||||
staerke = 2.2,
|
||||
farbe = '#5b4636',
|
||||
deckkraft = 1,
|
||||
frame,
|
||||
}) => {
|
||||
const jetzt = useCurrentFrame();
|
||||
const f = frame ?? jetzt;
|
||||
const dx = nach.x - von.x;
|
||||
const dy = nach.y - von.y;
|
||||
const laenge = Math.hypot(dx, dy) || 1;
|
||||
// Senkrechte zur Schnur, so gewählt, dass sie nach unten zeigt (Durchhang)
|
||||
let nx = -dy / laenge;
|
||||
let ny = dx / laenge;
|
||||
if (ny < 0) {
|
||||
nx = -nx;
|
||||
ny = -ny;
|
||||
}
|
||||
// Durchhang atmet ein wenig mit dem Wind; die Schnur schlängelt sich leicht
|
||||
const hang = laenge * durchhang * (1 + 0.15 * Math.sin(f * 0.09));
|
||||
const welle1 = Math.sin(f * 0.21) * wind;
|
||||
const welle2 = Math.sin(f * 0.17 + 1.3) * wind * 0.6;
|
||||
const k1 = {x: von.x + dx * 0.33 + nx * (hang * 0.9 + welle1), y: von.y + dy * 0.33 + ny * (hang * 0.9 + welle1)};
|
||||
const k2 = {x: von.x + dx * 0.66 + nx * (hang * 0.7 - welle2), y: von.y + dy * 0.66 + ny * (hang * 0.7 - welle2)};
|
||||
const d = `M ${von.x} ${von.y} C ${k1.x} ${k1.y}, ${k2.x} ${k2.y}, ${nach.x} ${nach.y}`;
|
||||
return (
|
||||
<svg style={{position: 'absolute', left: 0, top: 0, width: 1920, height: 1080, overflow: 'visible', pointerEvents: 'none', opacity: deckkraft}}>
|
||||
<path d={d} fill="none" stroke={farbe} strokeWidth={staerke} strokeLinecap="round" opacity={0.85} />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
32
remotion/src/szenen/DrachenschnurTest.tsx
Normal file
32
remotion/src/szenen/DrachenschnurTest.tsx
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import React from 'react';
|
||||
import {AbsoluteFill, useCurrentFrame} from 'remotion';
|
||||
import {Figur, NOA_HOEHE} from '../baukasten/figur';
|
||||
import {Drachenschnur, spulenPunkt} from '../baukasten/drachenschnur';
|
||||
|
||||
// Prüfszene: Noa mit Drachenspule, Schnur zu einem Platzhalter-Drachen, der pendelt.
|
||||
// Links normal, rechts gespiegelt und größer (prüft die Umrechnung).
|
||||
const Platzhalter: React.FC<{x: number; y: number}> = ({x, y}) => (
|
||||
<div style={{position: 'absolute', left: x - 40, top: y - 55, width: 80, height: 110}}>
|
||||
<svg width={80} height={110}>
|
||||
<polygon points="40,0 80,45 40,110 0,45" fill="#c8402c" opacity={0.8} />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const DrachenschnurTest: React.FC = () => {
|
||||
const f = useCurrentFrame();
|
||||
const drachen1 = {x: 760 + Math.sin(f * 0.05) * 60, y: 160 + Math.sin(f * 0.08) * 25};
|
||||
const drachen2 = {x: 1180 - Math.sin(f * 0.05) * 60, y: 200 + Math.cos(f * 0.07) * 25};
|
||||
const noa1 = {x: 420, y: 900, hoehe: NOA_HOEHE};
|
||||
const noa2 = {x: 1560, y: 980, hoehe: NOA_HOEHE * 1.5, spiegeln: true};
|
||||
return (
|
||||
<AbsoluteFill style={{background: '#f4ead8'}}>
|
||||
<Platzhalter {...drachen1} />
|
||||
<Platzhalter {...drachen2} />
|
||||
<Figur pose="noa_A_drachenschnur" {...noa1} />
|
||||
<Drachenschnur von={spulenPunkt(noa1.x, noa1.y, noa1.hoehe)} nach={{x: drachen1.x, y: drachen1.y + 55}} />
|
||||
<Figur pose="noa_A_drachenschnur" {...noa2} />
|
||||
<Drachenschnur von={spulenPunkt(noa2.x, noa2.y, noa2.hoehe, true)} nach={{x: drachen2.x, y: drachen2.y + 55}} staerke={3} durchhang={0.1} />
|
||||
</AbsoluteFill>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in a new issue