Dies ist eine Anleitung für das Schreiben von Remotion React Markup. Wenn dies nicht relevant ist, lade stattdessen die Remotion Best Practices.
Benutzeränderungen bewahren
Benutzer können außerhalb des Gesprächs Code-Änderungen vornehmen.
Wenn du zwischenzeitlich eine überraschende Änderung bemerkst, überschreibe sie nicht, sondern nimm an, sie sei beabsichtigt, oder frage nach Bestätigung.
Allgemeine Regeln
Innerhalb einer Composition oder eines Szenen-Komponenten erhältst du fps aus useVideoConfig() für
alle Sekunden-zu-Frames-Berechnungen, einschließlich Timing-Props wie from,
trimBefore, durationInFrames und premountFor. Wenn der Ausdruck auf dem
JSX-Knoten bleibt, z. B. trimBefore={4 * fps}, kann das Studio das Timing bearbeiten und
es bleibt korrekt, wenn sich die Bildrate der Composition ändert.
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.
Strukturiere dein Markup gemäß den Remotion Interactivity Best Practices.
Bevorzuge Interactive.withSchema({wrapInSequence: true, layout: 'absolute-fill'})
für Szenen mit editierbaren Props. Deren inneres Markup kann ein Fragment zurückgeben; der
Wrapper übernimmt Layout und Instanz-Styles. Dimensionierte Elemente wie Lower Thirds
können das Standard-Layout behalten und style an ihre eigene Wurzel weiterleiten. Registriere
wiederverwendbare Szenen als verbundene Compositions.
Setze Timing direkt auf Komponenten, die es unterstützen; vermeide redundante <Sequence>-Wrapper.
Gib jeder zeitgesteuerten Komponente, die premountFor unterstützt, eine Sekunde Vorlauf:
premountFor={fps}, wobei fps aus useVideoConfig() stammt. Wende dies auf
Medien, interaktive Komponenten, <Sequence>, <TransitionSeries.Sequence>,
und <TransitionSeries.Overlay> an, einschließlich zeitgesteuerter Komponenten innerhalb von Szenen. Lade auch das übergeordnete Timeline-Element vor,
wenn ein verschachteltes Element gemountet werden muss, bevor das übergeordnete startet. Eine Komponente ohne
premountFor, wie <TransitionSeries.Transition>, benötigt keinen Ersatz.
Das Studio bearbeitet den JSX-Quellknoten, der ein Element erstellt hat. Verfasse jede Composition-Registrierung, jeden Clip, jede Szene, jede Ebene und jede Sequenz, die unabhängig editierbar sein soll, als eigenen JSX-Knoten, mit ihren editierbaren Props inline. Programmatische Schleifen sind geeignet, wenn die generierten Instanzen absichtlich als eine Quellvorlage gesteuert werden, nicht wenn Benutzer die Instanzen separat bearbeiten müssen.
import { useCurrentFrame, useVideoConfig, Easing, interpolate, Interactive } from "remotion";
export const FadeIn = () => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
return (
<Interactive.Div
name="Title"
premountFor={fps}
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-Prop.
Verwende scale, translate, rotate CSS-Eigenschaften gegenüber 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 "output: 'perceptual-scale'" verwenden
}),
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 Projektstammverzeichnis ab.
Verwende staticFile(), um Dateien aus dem public/-Ordner zu referenzieren.
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 verwendet wird.
Verwende staticFile() für Dateien in public/ oder übergib eine Remote-URL direkt:
import { Audio, Video } from "@remotion/media";
import { staticFile, CanvasImage, AnimatedImage, useVideoConfig } from "remotion";
export const MyComposition = () => {
const {fps} = useVideoConfig();
return (
<>
<Video src={staticFile("video.mp4")} premountFor={fps} style={{ opacity: 0.5 }} />
<Audio src={staticFile("audio.mp3")} premountFor={fps} />
<CanvasImage
src={staticFile("logo.png")}
premountFor={fps}
style={{ width: 100, height: 100 }}
/>
<Video src="https://remotion.media/video.mp4" premountFor={fps} />
<AnimatedImage src={staticFile('nyancat.gif')} premountFor={fps} />
</>
);
};
Wenn die Composition hauptsächlich aus einer Timeline von Video- oder Audioclips besteht, lies video-editing.md, bevor du die Quellstruktur wählst.
Beispielszene
Ein Hintergrundvideo mit einem Lower Third.
Der Lower Third ist eine interaktive Komponente mit eigener Timeline, registriert als verbundene Composition.
Sein Text wird als children übergeben und accentColor ist ein editierbares Prop.
Die Einblendung wird inline am Aufrufort keyframed.
// MyScene.tsx
import { Video } from "@remotion/media";
import { Easing, interpolate, useCurrentFrame, useVideoConfig } from "remotion";
import { LowerThird } from "./LowerThird";
export const MyScene = () => {
const { fps } = useVideoConfig();
const frame = useCurrentFrame();
return (
<>
<Video
name="Background"
src="https://remotion.media/video.mp4"
premountFor={fps}
objectFit="cover"
style={{
position: "absolute",
width: "100%",
height: "100%",
}}
/>
<LowerThird
name="Lower third"
from={1 * fps}
premountFor={fps}
accentColor="#0b84f3"
style={{
opacity: interpolate(frame, [1 * fps, 2 * fps], [0, 1], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: Easing.bezier(0.16, 1, 0.3, 1),
}),
}}
>
Jane Doe, Product Designer
</LowerThird>
</>
);
};
// LowerThird.tsx
import type React from "react";
import { Interactive, type InteractivitySchema } from "remotion";
type LowerThirdProps = {
readonly children: React.ReactNode;
readonly accentColor: string;
readonly style?: React.CSSProperties;
};
const LowerThirdInner: React.FC<LowerThirdProps> = ({
children,
accentColor,
style,
}) => {
return (
<Interactive.Div
style={{
position: "absolute",
left: 80,
bottom: 80,
display: "flex",
alignItems: "center",
gap: 20,
backgroundColor: "white",
borderRadius: 16,
padding: "20px 32px",
color: "black",
fontFamily: "Helvetica, Arial, sans-serif",
fontSize: 48,
fontWeight: 600,
...style,
}}
>
<div
style={{
width: 8,
alignSelf: "stretch",
borderRadius: 4,
backgroundColor: accentColor,
}}
/>
{children}
</Interactive.Div>
);
};
const lowerThirdSchema = {
...Interactive.childrenSchema,
accentColor: {
type: "color",
default: "#0b84f3",
description: "Akzentfarbe",
},
} as const satisfies InteractivitySchema;
export const LowerThird = Interactive.withSchema({
Component: LowerThirdInner,
componentName: "LowerThird",
schema: lowerThirdSchema,
wrapInSequence: true,
});
import { Composition } from "remotion";
import { LowerThird } from "./LowerThird";
import { MyScene } from "./MyScene";
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="MyScene"
component={MyScene}
durationInFrames={60}
fps={30}
width={1280}
height={720}
/>
<Composition
id="LowerThird"
component={LowerThird}
durationInFrames={30}
fps={30}
width={1280}
height={720}
defaultProps={{
children: "Jane Doe, Product Designer",
accentColor: "#0b84f3",
}}
/>
</>
);
};
Verzögerung und Zuschnitt
Setze Timing direkt auf Komponenten, die es unterstützen. Siehe Timing-Props für die unterstützten Props, Beispiele und die Reihenfolge der Operationen.
Karten
Siehe Remotion Maps, falls Karten im Video enthalten sein sollen.
Texthervorhebungen und Annotationen
Siehe text-highlights.md für Texthervorhebungen (Highlight-Marker), Kreise, Unterstreichungen, Durchstreichungen, durchgestrichenen Text, Boxen.
Videos mit mehreren Szenen
Siehe multi-scene-video.md, falls du ein Video mit mehreren aufeinanderfolgenden Szenen erstellen möchtest.
Verbundene Compositions
Wenn eine Szene oder eine Gruppe von Ebenen eine eigene editierbare Timeline verdient, folge connected-compositions.md. Bevorzuge diese Struktur für umfangreiche Szenen in einem Video mit mehreren Szenen.
Pre-compose-Aktion
Für eine Studio-Anfrage wie Pre-compose Ambient glow (src/BarChart.tsx:134) finde das ausgewählte Sequenz-Markup an der angegebenen Stelle. Erstelle eine verbundene Composition gemäß connected-compositions.md: extrahiere das Markup in eine benannte Komponente, mache sie vorzugsweise interaktiv mit Interactive.withSchema({wrapInSequence: true}) und registriere denselben exportierten Komponentenverweis mit einer eindeutigen <Composition> im Root. Rendere die interaktive Komponente direkt mit ihren Timing-Props oder als einziges Kind einer Sequenz, wenn dieser Wrapper einen Zweck erfüllt. Wenn der ausgewählte Knoten bereits eine Sequenz ist, behalte seine Props und extrahiere seine Kinder. Die Registrierung benötigt Abmessungen, fps, Dauer und defaultProps äquivalent zur übergeordneten Verwendung. Eine Komponentenextraktion ohne registrierte Composition erfüllt eine Pre-compose-Anfrage nicht.
Übernimm vererbte Styles wie fontFamily und Schriftart-Ladung in die extrahierte
Komponente; siehe Elternunabhängigkeit.
Voiceover
Siehe voiceover.md zum Hinzufügen eines KI-generierten Voiceovers zu Remotion-Compositions mit ElevenLabs TTS.
Videos einbetten
Siehe embedding-videos.md für fortgeschrittenes Wissen zum Einbetten von Videos - Zuschnitt, Lautstärke, Geschwindigkeit, Schleifen, Tonhöhe.
Audio einbetten
Siehe audio.md für fortgeschrittene Audio-Funktionen wie Zuschnitt, Lautstärke, Geschwindigkeit, Tonhöhe.
Zuschneiden
Siehe cropping.md, falls das sichtbare Rechteck einer Komponente beschnitten werden muss.
Übergänge
Siehe transitions.md für Szenenübergangsmuster.
Bewegungsunschärfe
Wenn du Bewegungsunschärfe oder eine Bewegungsspur hinzufügen möchtest, lies motion-blur.md für den bevorzugten HTML-in-Canvas-Ansatz, Vorschauanforderungen und Alternativen.
Visuelle und Pixel-Effekte
Wenn du einen visuellen Effekt hinzufügen möchtest, identifiziere zuerst das Element oder die Gruppe, die er betreffen soll.
Wenn die Zielkomponente effects unterstützt und ein unten aufgeführtes, integriertes Effekt dem
Wunsch entspricht, bevorzuge diesen Effekt gegenüber einer CSS-Näherung. Wende z. B.
vignette() direkt auf das effects-Prop eines <Video> an, wenn die Vignette
nur dieses Video betreffen soll.
Diese Komponenten akzeptieren effects direkt:
| Import von | Komponenten |
|---|---|
remotion | <Img>, <CanvasImage>, <AnimatedImage>, <Solid>, <HtmlInCanvas> |
@remotion/media | <Video> |
@remotion/gif | <Gif> |
@remotion/rive | <RemotionRiveCanvas> |
@remotion/shapes | <Arrow>, <Callout>, <Circle>, <Ellipse>, <Heart>, <Pie>, <Polygon>, <Rect>, <Spark>, <Star>, <Triangle> |
Gewöhnliche HTML-Elemente, <Interactive.*>-DOM-Wrapper, <AbsoluteFill> und
<Sequence> akzeptieren effects nicht direkt. Um Effekte auf ihren Inhalt anzuwenden,
wickele sie in <HtmlInCanvas> ein und setze das effects-Prop auf den Wrapper.
Für andere Elemente bevorzuge reguläres HTML und CSS, wo geeignet. Ziehe in Betracht, eine Gruppe
in <HtmlInCanvas> einzuwickeln, wenn eine Nachbearbeitung der gesamten Gruppe
angemessen ist und die Umgebung dies unterstützt.
Lies effects.md, bevor du einen Effekt anwendest, für Importe, Parameter
und Einrichtung. Es behandelt auch wiederverwendbare benutzerdefinierte Effekte mit createEffect(), wenn kein
integrierter Effekt passt.
Verfügbare Effekte
Integrierte Effekte aus @remotion/effects:
- Farbe und Ton:
brightness(),colorCorrection(),colorKey(),contrast(),duotone(),exposure(),grayscale(),hue(),invert(),levels(),linearGradient(),linearGradientTint(),lut(),saturation(),shadowsHighlights(),thermalVision(),tint(),vibrance(),whiteBalance(). - Unschärfe und Spuren:
blur(),lightTrail(),linearProgressiveBlur(),radialProgressiveBlur(),regionBlur(),trail(). - Verzerrung und Überlagerung:
bend(),chromaticAberration(),codeRain(),colorMatrix(),colorReplace(),convolution(),crt(),displacementMap(),distanceBlur(),dropShadow(),dust(),edgeWork(),emboss(),filmGrain(),fisheye(),flash(),gaussianBlur(),glitch(),glow(),grainMerge(),hueRotate(),innerShadow(),kaleidoscope(),lens(),lightLeaks(),mirror(),noise(),oldFilm(),outline(),overlay(),pageCurl(),perspective(),pinch(),pixelate(),polaroid(),posterize(),pulse(),radialBlur(),ripple(),rotate3d(),saturate(),sepia(),sharpen(),sketch(),slitscan(),smoke(),solarize(),speedLines(),splash(),strobe(),swirl(),textureOverlay(),threshold(),tiltShift(),timeBlur(),tornEdges(),twin(),vignette(),water(),wave(),wind().
Weitere Details zu Parametern und Standardwerten findest du in effects.md.