Dies ist eine Anleitung zum Schreiben von Remotion React Markup. Falls dies nicht relevant ist, lade stattdessen die Remotion Best Practices.
Benutzeränderungen beibehalten
Benutzer können außerhalb des Gesprächs Änderungen am Code vornehmen.
Wenn du eine überraschende Änderung bemerkst, die in der Zwischenzeit gemacht wurde, überschreibe sie nicht, gehe davon aus, dass sie beabsichtigt ist, oder frage nach Bestätigung.
Allgemeine Regeln
Innerhalb einer Komposition oder einer Szenenkomponente erhältst du fps aus useVideoConfig() für
alle Sekunden-zu-Frames-Berechnungen, einschließlich Timing-Props wie from,
trimBefore, durationInFrames und premountFor. Wenn du den Ausdruck auf dem
JSX-Knoten belässt, wie z. B. trimBefore={4 * fps}, ermöglicht dies dem Studio, das Timing zu bearbeiten und
es korrekt zu halten, wenn sich die Bildrate der Komposition ändert.
Treibe Animationen mit useCurrentFrame() und interpolate() an.
CSS transition oder animation werden nicht korrekt gerendert, sie müssen umgestaltet werden.
Tailwind-Animation-Klassen werden nicht korrekt gerendert, sie 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. Ihr inneres Markup kann ein Fragment zurückgeben; der
Wrapper kümmert sich um das Layout und die Instanzstile. Bemaßte Elemente wie Lower Thirds
können das Standardlayout behalten und style an ihre eigene Root weiterleiten. Registriere
wiederverwendbare Szenen als verbundene Kompositionen.
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 von useVideoConfig() kommt. Wende dies auf
Medien, interaktive Komponenten, <Sequence>, <TransitionSeries.Sequence>
und <TransitionSeries.Overlay> an, einschließlich zeitgesteuerter Komponenten, die in Szenen verschachtelt sind. Vorladen auch das übergeordnete Timeline-Element,
wenn ein verschachteltes Element bereitgestellt werden muss, bevor das übergeordnete Element startet. Eine Komponente ohne
premountFor, wie z. B. <TransitionSeries.Transition>, benötigt keinen Ersatz.
Das Studio bearbeitet den JSX-Quellknoten, der ein Element erstellt hat. Erstelle jede Kompositionsregistrierung, jeden Clip, jede Szene, jede Ebene und jede Sequenz, die unabhängig bearbeitet werden soll, als eigenen JSX-Knoten mit seinen editierbaren Props inline. Programmatische Schleifen sind geeignet, wenn die generierten Instanzen absichtlich als eine einzige 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>
);
};
Belasse den interpolate()-Aufruf inline im style-Prop.
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' // Verwende für `scale`-Animationen "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 werden im Studio schwerer zu bearbeiten
const scale = interpolate(frame, [0, 100], [0, 1]);
style={{
transform: `scale(${scale})`,
}}
Assets
Platziere Assets im public/-Ordner im Stammverzeichnis deines Projekts.
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, wenn nicht Chrome verwendet wird.
Verwende staticFile() für Dateien in public/ oder gib direkt eine Remote-URL an:
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 Komposition hauptsächlich eine Zeitleiste von Video- oder Audio-Clips ist, lies video-editing.md, bevor du ihre Quellstruktur auswählst.
Beispielszene
Ein Hintergrundvideo mit einem Lower Third.
Der Lower Third ist eine interaktive Komponente mit eigener Zeitleiste, registriert als verbundene Komposition.
Sein Text wird als children übergeben und accentColor ist ein editierbares Prop.
Der Fade-In ist 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: "Accent color",
},
} 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, Trimmen
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, wenn Karten in das Video eingefügt werden sollen.
Texthervorhebungen und Anmerkungen
Siehe text-highlights.md für Texthervorhebungen (Hervorhebungsmarkierungen), Kreise, Unterstreichungen, Durchstreichungen, durchgestrichenen Text, Boxen.
Mehrszenen-Videos
Siehe multi-scene-video.md, wenn ein Video mit mehreren aufeinanderfolgenden Szenen erstellt werden soll.
Verbundene Kompositionen
Wenn eine Szene oder eine Gruppe von Ebenen eine eigene editierbare Zeitleiste verdient, folge connected-compositions.md. Bevorzuge diese Struktur für umfangreiche Szenen in einem Mehrszenen-Video.
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 Komposition gemäß connected-compositions.md: extrahiere das Markup in eine benannte Komponente, mache sie vorzugsweise interaktiv mit Interactive.withSchema({wrapInSequence: true}) und registriere dieselbe exportierte Komponentenreferenz mit einem eindeutigen <Composition> in der Root. Rendere die interaktive Komponente direkt mit ihren Timing-Props oder als einziges Kind einer Sequenz, wenn dieser Wrapper einen Zweck hat. Wenn der ausgewählte Knoten bereits eine Sequenz ist, behalte ihre Props und extrahiere ihre Kinder. Die Registrierung benötigt Abmessungen, fps, Dauer und defaultProps, die der Verwendung im übergeordneten Element entsprechen. Eine Komponentenextraktion ohne registrierte Komposition schließt eine Pre-compose-Anfrage nicht ab.
Übernimm geerbte Styles wie fontFamily und das Laden von Schriftarten in die extrahierte
Komponente; siehe Elternunabhängigkeit.
Voiceover
Siehe voiceover.md zum Hinzufügen eines KI-generierten Voiceovers zu Remotion-Kompositionen mit ElevenLabs TTS.
Einbetten von Videos
Siehe embedding-videos.md für fortgeschrittenes Wissen über das Einbetten von Videos - Trimmen, Lautstärke, Geschwindigkeit, Schleifen, Tonhöhe.
Einbetten von Audio
Siehe audio.md für fortgeschrittene Audiofunktionen wie Trimmen, Lautstärke, Geschwindigkeit, Tonhöhe.
Zuschneiden
Siehe cropping.md, wenn das sichtbare Rechteck einer Komponente zugeschnitten werden muss.
Übergänge
Siehe transitions.md für Szenenübergangsmuster.
Bewegungsunschärfe
Wenn Bewegungsunschärfe oder eine Bewegungsspur hinzugefügt werden soll, lies motion-blur.md für den bevorzugten HTML-in-Canvas-Ansatz, Vorschauanforderungen und Alternativen.
Visuelle und Pixeleffekte
Wenn ein visueller Effekt hinzugefügt wird, identifiziere zuerst das Element oder die Gruppe, die er betreffen soll.
Wenn die Zielkomponente effects und einen der unten aufgeführten integrierten Effekte unterstützt,
bevorzuge diesen Effekt gegenüber einer CSS-Näherung. Zum Beispiel wende
vignette() direkt auf das effects-Prop eines <Video> an, wenn die Vignette 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> und setze das effects-Prop auf den Wrapper.
Für andere Elemente bevorzuge normales HTML und CSS, wo geeignet. Erwäge, eine Gruppe
in <HtmlInCanvas> zu wickeln, wenn eine Nachbearbeitung der gesamten Gruppe
geeignet ist und die Umgebung dies unterstützt.
Lies effects.md, bevor du einen Effekt für Imports, Parameter
und Einrichtung anwendest. 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,shadow(),smoothEdges(),spread(),vignette(). - Verzerrung und Rauschen:
crt(),glitch(),noise(),pixelate(),radialGrid(),scanlines(),vhs(). - Compositing:
blend(),chromaKey(),colorReplace(),displacementMap(),lumaKey(),mask(),texture(). - Transformation:
flip(),perspective(),shake(). - Stilisiert:
edge(),emboss(),glow(),kaleidoscope(),neon(),outline(),posterize(),sepia(),sketch().