OfficialVidéo et animationgithub.com

remotion-markup

Bonnes pratiques pour le contenu, l'animation et les effets dans Remotion.

Qu'est-ce que remotion-markup ?

Ce skill fournit des directives complètes pour l'écriture de code React dans Remotion, en se concentrant sur les bonnes pratiques pour le contenu, l'animation et les effets. Il est conçu pour les développeurs qui utilisent Remotion pour créer des vidéos programmatiques et couvre les règles essentielles telles que l'utilisation de `useCurrentFrame()` et `interpolate()` pour les animations, l'évitement des transitions CSS et des animations Tailwind, et l'emploi de `Easing.bezier()` et `Easing.spring()` pour un contrôle précis du timing. Le skill met l'accent sur la préservation des modifications utilisateur et l'importance d'utiliser `fps` depuis `useVideoConfig()` pour tous les calculs de trames. Il prend en charge plusieurs plateformes (Claude Code, Cursor, Codex) et inclut des exemples pratiques pour divers scénarios : composants interactifs avec `Interactive.withSchema()`, gestion des médias (vidéo, audio, images animées), placements d'actifs dans le dossier `public/`, et structuration de scènes multi-scènes avec des compositions connectées. De plus, il couvre les effets visuels et les transitions, en indiquant quels composants acceptent directement la prop `effects` (par exemple `<Video>`, `<CanvasImage>`) et comment utiliser `<HtmlInCanvas>` pour appliquer des effets à des éléments HTML classiques. Les développeurs y trouveront aussi des conseils sur le délai, le recadrage, le flou de mouvement, et les annotations de texte via des fichiers séparés (comme `timing-props.md`, `transitions.md`, `text-highlights.md`).

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

Installed? Explore more Vidéo et animation skills: steipete/video-frames, steipete/summarize, openclaw/openclaw · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Aperçu

Depuis le README du skill

Documentation

Ceci est un guide pour écrire du markup React Remotion. Si cela n'est pas pertinent, chargez plutôt Remotion Best Practices.

Préserver les modifications utilisateur

Les utilisateurs peuvent apporter des modifications au code en dehors de la conversation.

Si vous détectez un changement surprenant effectué entre-temps, ne l'écrasez pas, supposez qu'il était intentionnel ou demandez une confirmation.

Règles générales

À l'intérieur d'un composant de composition ou de scène, obtenez fps de useVideoConfig() pour tous les calculs secondes-à-trames, y compris les propriétés de timing telles que from, trimBefore, durationInFrames, et premountFor. Garder l'expression sur le nœud JSX, comme trimBefore={4 * fps}, permet à Studio de modifier le timing et le maintient correct si la fréquence d'images de la composition change.

Conduisez les animations en utilisant useCurrentFrame() et interpolate(). Les transition ou animation CSS ne seront pas rendues correctement, elles doivent être refactorisées. Les classes d'animation Tailwind ne seront pas rendues correctement, elles doivent être refactorisées.

Utilisez Easing.bezier() et Easing.spring() pour personnaliser le timing.

Structurez votre markup selon les meilleures pratiques d'interactivité Remotion. Préférez Interactive.withSchema({wrapInSequence: true, layout: 'absolute-fill'}) pour les scènes avec des propriétés modifiables. Leur markup interne peut retourner un fragment ; le wrapper gère la mise en page et les styles d'instance. Les éléments dimensionnés tels que les tiers inférieurs peuvent conserver la mise en page par défaut et transmettre style à leur propre racine. Enregistrez les scènes réutilisables en tant que compositions connectées. Placez le timing directement sur les composants qui le supportent ; évitez les wrappers <Sequence> redondants. Donnez à chaque composant temporisé qui supporte premountFor une seconde de pré-montage : premountFor={fps}, où fps provient de useVideoConfig(). Appliquez ceci aux médias, composants interactifs, <Sequence>, <TransitionSeries.Sequence>, et <TransitionSeries.Overlay>, y compris les composants temporisés imbriqués dans les scènes. Pré-montez également l'élément parent de la timeline lorsqu'un élément imbriqué doit se monter avant que le parent ne commence. Un composant sans premountFor, tel que <TransitionSeries.Transition>, n'a besoin d'aucun substitut.

Le Studio modifie le nœud source JSX qui a créé un élément. Créez chaque enregistrement de composition, clip, scène, calque et séquence qui doit être modifiable indépendamment comme son propre nœud JSX, avec ses propriétés modifiables en ligne. Les boucles programmatiques sont appropriées lorsque les instances générées sont intentionnellement contrôlées comme un modèle source unique, pas lorsque les utilisateurs ont besoin de modifier les instances séparément.

import { useCurrentFrame, useVideoConfig, Easing, interpolate, Interactive } from "remotion";

export const FadeIn = () => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();

  return (
    <Interactive.Div
      name="Titre"
      premountFor={fps}
      style={{
        opacity: interpolate(frame, [0, 2 * fps], [0, 1], {
          extrapolateRight: "clamp",
          extrapolateLeft: "clamp",
          easing: Easing.bezier(0.16, 1, 0.3, 1),
        }),
      }}
    >
      Bonjour le monde !
    </Interactive.Div>
  );
};

Gardez l'appel interpolate() en ligne dans la propriété style. Utilisez les propriétés CSS scale, translate, rotate plutôt que transform.

// 👍 Images clés modifiables en ligne et raccourcis de transformation
style={{
  scale: interpolate(frame, [0, 100], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: Easing.spring({damping: 200}),
    output: 'perceptual-scale' // Pour les animations `scale`, utilisez "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}),
  }),
}}

// 👎 Les valeurs non en ligne et les chaînes de transformation deviennent plus difficiles à modifier dans Studio
const scale = interpolate(frame, [0, 100], [0, 1]);

style={{
  transform: `scale(${scale})`,
}}

Actifs

Placez les actifs dans le dossier public/ à la racine de votre projet. Utilisez staticFile() pour référencer des fichiers depuis le dossier public/.

Composants médias

Ajoutez de la vidéo et de l'audio en utilisant <Video> et <Audio> d'@remotion/media. Ajoutez des images en utilisant le composant <CanvasImage>. Ajoutez des GIF animés, APNG, WebP ou des images AVIF en utilisant <AnimatedImage>, utilisez @remotion/gif si vous n'utilisez pas Chrome. Utilisez staticFile() pour les fichiers dans public/ ou transmettez une URL distante directement :

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} />
    </>
  );
};

Si la composition est principalement une timeline de clips vidéo ou audio, lisez video-editing.md avant de choisir sa structure source.

Exemple de scène

Une vidéo de fond avec un tiers inférieur. Le tiers inférieur est un composant interactif avec sa propre timeline, enregistré comme composition connectée. Son texte est passé comme children et accentColor est une propriété modifiable. La fondu entrant est animé en ligne sur le site d'appel.

// 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="Arrière-plan"
        src="https://remotion.media/video.mp4"
        premountFor={fps}
        objectFit="cover"
        style={{
          position: "absolute",
          width: "100%",
          height: "100%",
        }}
      />
      <LowerThird
        name="Tiers inférieur"
        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, Designer Produit
      </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: "Couleur d'accentuation",
  },
} 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, Designer Produit",
          accentColor: "#0b84f3",
        }}
      />
    </>
  );
};

Délai, rognage

Mettez le timing directement sur les composants qui le supportent. Voir Propriétés de timing pour les propriétés prises en charge, des exemples et l'ordre des opérations.

Cartes

Consultez Remotion Maps si vous souhaitez inclure des cartes dans la vidéo.

Surlignements et annotations de texte

Voir text-highlights.md pour les surlignements de texte (marqueurs de surbrillance), les cercles, les soulignements, les barrés, le texte rayé, les boîtes.

Vidéos multi-scènes

Voir multi-scene-video.md si vous prévoyez de réaliser une vidéo avec plusieurs scènes consécutives.

Compositions connectées

Lorsqu'une scène ou un groupe de calques mérite sa propre timeline modifiable, suivez connected-compositions.md. Préférez cette structure pour les scènes importantes dans une vidéo multi-scènes.

Action de pré-composition

Pour une demande Studio telle que Pré-composer la lueur ambiante (src/BarChart.tsx:134), trouvez le markup de séquence sélectionné à l'emplacement donné. Créez une composition connectée, en suivant connected-compositions.md : extrayez le markup dans un composant nommé, de préférence rendez-le interactif avec Interactive.withSchema({wrapInSequence: true}), et enregistrez la même référence de composant exportée avec un <Composition> unique dans la racine. Rendez le composant interactif directement avec ses propriétés de timing, ou comme le seul enfant d'une séquence lorsque ce wrapper a un but. Si le nœud sélectionné est déjà une séquence, conservez ses propriétés et extrayez ses enfants. L'enregistrement a besoin des dimensions, fps, durée et defaultProps équivalents à son utilisation parent. Une extraction de composant sans composition enregistrée ne complète pas une demande de pré-composition.

Transportez les styles hérités tels que fontFamily et le chargement de police dans le composant extrait ; voir indépendance parent.

Voix off

Voir voiceover.md pour ajouter une voix off générée par IA aux compositions Remotion en utilisant ElevenLabs TTS.

Incorporation de vidéos

Voir embedding-videos.md pour des connaissances avancées sur l'incorporation de vidéos - rognage, volume, vitesse, bouclage, hauteur.

Incorporation d'audio

Voir audio.md pour des fonctionnalités audio avancées comme le rognage, le volume, la vitesse, la hauteur.

Recadrage

Voir cropping.md si vous avez besoin de recadrer le rectangle visible d'un composant.

Transitions

Voir transitions.md pour les modèles de transition de scène.

Flou de mouvement

Lors de l'ajout d'un flou de mouvement ou d'une traînée de mouvement, lisez motion-blur.md pour l'approche préférée HTML-dans-canvas, les exigences de prévisualisation et les alternatives.

Effets visuels et pixel

Lors de l'ajout d'un effet visuel, identifiez d'abord l'élément ou le groupe qu'il doit affecter. Si le composant cible prend en charge effects et qu'un effet intégré ci-dessous correspond à la demande, préférez cet effet à une approximation CSS. Par exemple, appliquez vignette() directement à la prop effects d'un <Video> lorsque la vignette doit affecter cette vidéo.

Ces composants acceptent effects directement :

Importer deComposants
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>

Les éléments HTML ordinaires, les wrappers DOM <Interactive.*>, <AbsoluteFill> et <Sequence> n'acceptent pas effects directement. Pour appliquer des effets à leur contenu, enveloppez-les dans <HtmlInCanvas> et placez la prop effects sur le wrapper.

Pour d'autres éléments, préférez le HTML et le CSS standard lorsque c'est approprié. Envisagez d'envelopper un groupe dans <HtmlInCanvas> lorsque le post-traitement de tout le groupe est approprié et que l'environnement le prend en charge.

Lisez effects.md avant d'appliquer un effet pour les imports, les paramètres et la configuration. Il couvre également les effets personnalisés réutilisables avec createEffect() lorsqu'aucun effet intégré ne correspond.

Effets disponibles

Effets intégrés depuis @remotion/effects :

  • Couleur et teinte : brightness(), colorCorrection(), colorKey(), contrast(), duotone(), exposure(), grayscale(), hue(), invert(), levels(), linearGradient(), linearGradientTint(), lut(), saturation(), shadowsHighlights(), thermalVision(), tint(), vibrance(), whiteBalance().
  • Flou et traînées : blur(), lightTrail(), linearProgressiveBlur(), radialProgressiveBlur(), regionBlur

Individual skills in this repo

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

Skills associés