OfficialVideo & Animationgithub.com

remotion-markup

Richtlinien für Inhalte, Animationen und Effekte in Remotion.

Was ist remotion-markup?

Diese Skill-Datei bietet umfassende Richtlinien zur Erstellung von Remotion React Markup, mit Schwerpunkt auf Content, Animationen und Effekte. Sie ist nützlich für Entwickler, die interaktive und editierbare Video-Szenen mit Remotion erstellen möchten. Die Richtlinien decken Best Practices für die Verwendung von `useCurrentFrame()` und `interpolate()` zur Frame-basierten Animation ab, betonen die Beibehaltung von Benutzeränderungen und erklären, wie man benutzerdefinierte Timing-Props wie `premountFor` und `durationInFrames` korrekt einsetzt. Die Skill unterstützt die Integration von Medienkomponenten (Video, Audio, Bilder) und deren Effekte, sowie die Strukturierung von Szenen mit `Interactive.withSchema()` und verbundenen Kompositionen. Sie enthält außerdem Anleitungen für Text-Highlights, Karten, Voiceover, Übergänge, Bewegungsunschärfe und visuelle Effekte, wobei stets empfohlen wird, Effekte direkt auf Komponenten zu setzen, die sie unterstützen, oder sie in `<HtmlInCanvas>` zu wrappen.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/remotion-dev/skills/tree/main/skills/remotion-markup

Installed? Explore more Video & Animation skills: steipete/video-frames, steipete/summarize, openclaw/openclaw · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Vorschau

Aus dem Skill-README

Dokumentation

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 vonKomponenten
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().

Individual skills in this repo

This repo contains 19 individual skills — each has its own dedicated page.

Verwandte Skills