Dies ist eine Anleitung zum Schreiben von Remotion React Markup. Falls dies nicht relevant ist, lade stattdessen die Remotion Best Practices.
Änderungen des Benutzers bewahren
Benutzer können während des Gesprächs Änderungen am Code außerhalb des Dialogs vornehmen.
Wenn du eine überraschende Änderung bemerkst, die in der Zwischenzeit gemacht wurde, überschreibe sie nicht, sondern geh davon aus, dass sie beabsichtigt war, oder frag nach Bestätigung.
Allgemeine Regeln
Steuere Animationen mit useCurrentFrame() und interpolate().
CSS transition oder animation werden nicht korrekt gerendert und müssen umgestaltet werden.
Tailwind-Animation-Klassen werden nicht korrekt gerendert und müssen umgestaltet werden.
Verwende Easing.bezier() und Easing.spring(), um das Timing anzupassen.
Gestalte dein Markup gemäß den Remotion Interactivity Best Practices
import { useCurrentFrame, Easing, interpolate, Interactive } from "remotion";
export const FadeIn = () => {
const frame = useCurrentFrame();
return (
<Interactive.Div
name="Title"
style={{
opacity: interpolate(frame, [0, 2 * fps], [0, 1], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: Easing.bezier(0.16, 1, 0.3, 1),
}),
}}
>
Hello World!
</Interactive.Div>
);
};
Behalte den interpolate()-Aufruf inline im style-Attribut.
Verwende die CSS-Eigenschaften scale, translate, rotate anstelle von transform.
// 👍 Inline editierbare Keyframes und Transform-Kurzformen
style={{
scale: interpolate(frame, [0, 100], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.spring({damping: 200}),
output: 'perceptual-scale' // Für `scale`-Animationen verwende "output: 'perceptual-scale'"
}),
translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.spring({damping: 200}),
}),
rotate: interpolate(frame, [0, 100], ["20deg", "90deg"], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.spring({damping: 200}),
}),
}}
// 👎 Nicht-inline Werte und Transform-Strings sind im Studio schwerer zu bearbeiten
const scale = interpolate(frame, [0, 100], [0, 1]);
style={{
transform: `scale(${scale})`,
}}
Assets
Lege Assets im public/-Ordner im Stammverzeichnis deines Projekts ab.
Verwende staticFile(), um auf Dateien aus dem public/-Ordner zu verweisen.
Medienkomponenten
Füge Video und Audio mit <Video> und <Audio> aus @remotion/media hinzu.
Füge Bilder mit der <CanvasImage>-Komponente hinzu.
Füge animierte GIFs, APNG, WebP oder AVIF-Bilder mit <AnimatedImage> hinzu, verwende @remotion/gif, falls nicht Chrome.
Verwende staticFile() für Dateien in public/ oder gib eine entfernte URL direkt an:
import { Audio, Video } from "@remotion/media";
import { staticFile, CanvasImage, AnimatedImage } from "remotion";
export const MyComposition = () => {
return (
<>
<Video src={staticFile("video.mp4")} style={{ opacity: 0.5 }} />
<Audio src={staticFile("audio.mp3")} />
<CanvasImage
src={staticFile("logo.png")}
style={{ width: 100, height: 100 }}
/>
<Video src="https://remotion.media/video.mp4" />
<AnimatedImage src={staticFile('nyancat.gif')} />
</>
);
};
Beispiel-Szene
import {
AbsoluteFill,
Easing,
Interactive,
interpolate,
useCurrentFrame,
useVideoConfig
} from "remotion";
export const Empty = () => {
const {fps} = useVideoConfig();
const frame = useCurrentFrame();
return (
<AbsoluteFill
name="Scene"
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}
>
<Interactive.Div
name="Title"
style={{
opacity: interpolate(frame, [1 * fps, 2 * fps], [0, 1], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: Easing.bezier(0.16, 1, 0.3, 1),
}),
fontSize: 88
}}
>
Title
</Interactive.Div>
<Interactive.Div
name="Subtitle"
style={{
opacity: interpolate(frame, [2 * fps, 3 * fps, 8 * fps, 10 * fps], [0, 1, 1, 0], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: [Easing.bezier(0.16, 1, 0.3, 1), Easing.linear, Easing.bezier(0.16, 1, 0.3, 1)],
}),
fontSize: 32
}}
>
Subtitle
</Interactive.Div>
</AbsoluteFill>
);
}
Verzögerung, Zuschneiden
Die meisten Komponenten (<AbsoluteFill>, <Interactive.*> <Img>, <AnimatedImage>, <CanvasImage>, <HtmlInCanvas>, <Solid>, <Sequence> aus remotion, <Video> und <Audio> aus @remotion/media, <Gif> und mehr) unterstützen die folgenden Props:
from
<Img from={1 * fps} {/* ... */}/>
<Video from={1 * fps} {/* ... */}/>
<Interactive.Div from={1 * fps} {/* ... */}/>
Gibt an, wann das Element in der Zeitleiste zu erscheinen beginnt.
durationInFrames
<Img durationInFrames={20 * fps} {/* ... */}/>
<Interactive.Div durationInFrames={20 * fps} {/* ... */}/>
Gibt an, wie lange die Ebene in der Zeitleiste abgespielt wird.
Für Medien gib die natürliche Dauer des Mediums an: <Video durationInFrames={29.322 * fps}/>
trimBefore
Nützlich für Komponenten, deren interne Uhr später starten soll:
// Die ersten 2 Sekunden des Materials wegschneiden
<Video trimBefore={2 * fps} {/* ... */} />
// `useCurrenFrame()` für Kinder beginnt bei `10 * fps`
<Sequence trimBefore={10 * fps} {/* ... */} />
Fallback
Falls eine Komponente diese Props nicht unterstützt, umschließe sie mit <Sequence> aus remotion, das diese Props besitzt.
layout="absolute-fill"lässt Sequence wie AbsoluteFill verhaltenlayout="none"ist der "Headless"-Modus, es wird kein Wrapper-Element verwendet.
Karten
Siehe Remotion Maps, falls Karten im Video eingebunden werden sollen.
Text-Highlights und Annotationen
Siehe text-highlights.md für Text-Highlights (Hervorhebungsmarkierungen), Kreise, Unterstreichungen, Durchstreichungen, durchgestrichenen Text, Boxen.
Multi-Szenen-Videos
Siehe multi-scene-video.md, falls du ein Video mit mehreren aufeinanderfolgenden Szenen erstellen möchtest.
Voiceover
Siehe voiceover.md zum Hinzufügen eines KI-generierten Voiceovers zu Remotion-Kompositionen mit ElevenLabs TTS.
Videos einbetten
Siehe embedding-videos.md für fortgeschrittenes Wissen zum Einbetten von Videos – Zuschneiden, Lautstärke, Geschwindigkeit, Schleifen, Tonhöhe.
Audio einbetten
Siehe audio.md für erweiterte Audio-Funktionen wie Zuschneiden, Lautstärke, Geschwindigkeit, Tonhöhe.
Videobearbeitung
Siehe video-editing.md zum Strukturieren bearbeitbarer Video-Zeitleisten im Remotion Studio.
Zuschneiden
Siehe cropping.md, falls das sichtbare Rechteck einer Komponente zugeschnitten werden muss.
Übergänge
Siehe transitions.md für Szenenübergangsmuster.
Visuelle und Pixeleffekte
Wenn du einen visuellen Effekt erstellst, überlege, ob dies mit CSS und HTML machbar ist oder ob ein Shader benötigt wird. Reihenfolge der Präferenz:
- Normales HTML + CSS oder andere Webtechniken
- Ein Effekt, der direkt auf das Element angewendet wird (
<Video>,<Img>), oder durch Umwickeln des Inhalts in<HtmlInCanvas>, das aucheffectsakzeptiert:
- Ein aufgelisteter Effekt über effects.md
- Ein benutzerdefinierter
createEffect()über effects.md, wenn kein voreingestellter Effekt verfügbar ist.
3D-Inhalte
Siehe ./3d.md für 3D-Inhalte in Remotion mit Three.js und React Three Fiber.
Soundeffekte
Wenn Soundeffekte benötigt werden, lade die Datei ./sfx.md für weitere Informationen.
Audio-Visualisierung
Wenn Audio visualisiert werden muss (Spektrum-Balken, Wellenformen, bassreaktive Effekte), lade die Datei ./audio-visualization.md für weitere Informationen.
Karten
Für statische Karten, animierte Routen und Marker, geografische Erklärungen, Mapbox, MapLibre, MapTiler, GeoJSON oder 3D-geografische Überflüge lade Remotion Maps.
Untertitel
Wenn es um Untertitel oder Bildunterschriften geht, lade die Remotion Captions Skill für weitere Informationen.
Google Fonts
Ist die empfohlene Methode, um Schriftarten in Remotion zu laden. Siehe google-fonts.md zum Laden von Google Fonts.
Lokale Schriftarten
Siehe local-fonts.md zum Laden lokaler Schriftarten.
GIFs
Siehe gifs.md zum Anzeigen von GIFs, die mit der Remotion-Zeitleiste synchronisiert sind.
Erweiterte Bilder
Siehe images.md zum Skalieren und Positionieren von Bildern, dynamischen Bildpfaden und zum Ermitteln von Bildabmessungen.
Lottie-Animationen
Siehe lottie.md zum Einbetten von Lottie-Animationen in Remotion.
Timing
Siehe timing.md für weitere Timing-Techniken für interpolate().
Parametrisierte Videos
Siehe parameters.md zum Erstellen einer parametrisierbaren Komposition durch Hinzufügen eines Zod-Schemas.
DOM-Knoten messen
Siehe measuring-dom-nodes.md zum Messen von DOM-Elementabmessungen in Remotion.
Text messen
Siehe measuring-text.md zum Messen von Textabmessungen, zum Anpassen von Text an Container und zur Überprüfung auf Überlauf.
FFmpeg verwenden
Für einige Videooperationen wie das Zuschneiden von Videos oder das Erkennen von Stille sollte FFmpeg verwendet werden. Lade die Datei ./ffmpeg.md für weitere Informationen.
Stille-Erkennung
Wenn stille Segmente aus Video- oder Audiodateien erkannt und zugeschnitten werden müssen, lade die Datei ./silence-detection.md.
Dynamische Dauer, Abmessungen und Daten
Siehe calculate-metadata.md zum dynamischen Festlegen von Kompositionsdauer, Abmessungen und Props.
Erweiterte Kompositionen
Siehe compositions.md zum Definieren von Standbildern, Ordnern, Standard-Props und zum Verschachteln von Kompositionen.
Erweiterte Sequenzierung
Siehe sequencing.md für weitere Sequenzierungsmuster – Verzögerung, Zuschneiden, Begrenzung der Dauer von Elementen.
Module installieren
Verwende npx remotion add, um neue Pakete mit der richtigen Version hinzuzufügen:
npx remotion add @remotion/media
Dies gilt für @remotion/*-Pakete, mediabunny, @mediabunny/* und zod.
Markup-Vorschau
npx remotion studio --no-open
Dies startet einen langlebigen Prozess und gibt die Server-URL für die Vorschau aus.
Falls der Server bereits gestartet ist, wird die URL ausgegeben.
Du kannst eine bestimmte Komposition besuchen, indem du zu /[composition-id] navigierst, zum Beispiel http://localhost:3000/MapAnimation.
Optional: Einzelbild-Render-Check
Du kannst ein einzelnes Bild mit der CLI rendern, um Layout, Farben oder Timing zu überprüfen. Überspringe dies bei trivialen Bearbeitungen, reinen Refactorings oder wenn du bereits genügend Vertrauen aus dem Studio oder früheren Renderings hast.
npx remotion still [composition-id] --scale=0.25 --frame=30
Bei 30 fps ist --frame=30 die Ein-Sekunden-Marke (--frame ist nullbasiert).