En écrivant le balisage Remotion d'une manière spécifique, le Studio Remotion peut reconnaître la structure du code et le rendre interactif :
- Permettre la sélection d'éléments en cliquant dessus
- Permettre le glisser-déposer, le redimensionnement et la rotation
- Éditer les styles CSS
- Rendre les images clés et les valeurs d'interpolation modifiables
Si le balisage est trop complexe pour que le Studio le rende interactif, les valeurs deviennent grisées.
Préférer les composants interactifs avec leurs propres timelines
Construisez de nouvelles compositions avec Track, des compositions connectées, et Interactive.create().
Définissez layout explicitement sur 'absolute-fill' pour les scènes ou 'none' pour les éléments délimités. Enregistrez les mêmes composants de scène et d'éléments réutilisables exportés avec Composition.
Commencez par l'exemple complet Track + compositions connectées. Il inclut l'élément, la scène, la timeline parente et les enregistrements racine.
import {Track, useVideoConfig} from 'remotion';
import {Chapter} from './Chapter';
export const MyVideo = () => {
const {fps} = useVideoConfig();
return (
<Track name="Chapitres">
<Chapter
name="Ouverture"
durationInFrames={3 * fps}
title="Introduction"
/>
<Chapter
name="Fonctionnalité"
from={3 * fps}
durationInFrames={4 * fps}
title="Nouvelles fonctionnalités"
/>
</Track>
);
};
Placez les styles d'arrière-plan et d'alignement sur chaque instance de scène, comme indiqué dans l'exemple complet. Conservez les conteneurs de mise en page uniquement en HTML simple.
Choisir les champs du schéma
Chaque clé dans le schéma est une propriété que le Studio peut lire et modifier au niveau de l'appel.
Les propriétés qui ne sont pas dans le schéma fonctionnent toujours, mais ne sont pas modifiables dans le Studio.
Les clés peuvent utiliser la notation par points, comme style.color.
| Type | Utilisation pour | Images clés possibles |
|---|---|---|
string | Chaînes de caractères, comme un titre, une invite ou un extrait de code | Non |
number | Nombres, avec min, max, step, integer optionnels | Oui |
boolean | Interrupteurs on/off | Oui (maintien) |
color | Chaînes de couleur CSS | Oui |
enum | Un choix entre des variants, chacun avec son propre schéma imbriqué | Optionnel (maintien) |
array | Listes de nombres, couleurs, énumérations et plus | Non |
asset | Sources média, avec assetType optionnel | Non |
font-family | Famille de police CSS | Non |
font-weight | Poids de police | Oui |
translate, scale, rotation-css, rotation-degrees, transform-origin | Transformations | Oui |
uv-coordinate | Un point normalisé [x, y] sur l'élément | Oui |
svg-path | Données de chemin SVG | Oui |
remotion-captions | Données Caption[] | Non |
hidden | Une valeur gardée hors des contrôles | — |
Chaque champ a besoin d'une default et devrait avoir une description, que le Studio affiche comme étiquette.
Définissez keyframable: false pour afficher un contrôle statique.
Exposez le contenu et l'apparence par instance, comme le texte et une couleur d'accentuation.
N'ajoutez pas de champs pour style.translate, style.scale, style.rotate, style.transformOrigin et style.opacity : Interactive.create() les ajoute automatiquement.
Pour rendre les propriétés CSS de la racine modifiables par instance, déployez les fragments de schéma intégrés :
const cardSchema = {
...Interactive.textSchema, // style.color, style.fontSize, style.fontWeight, ...
...Interactive.backgroundSchema, // style.backgroundColor
...Interactive.borderRadiusSchema, // style.borderRadius, ...
} as const satisfies InteractivitySchema;
Également disponibles : Interactive.borderSchema, et Interactive.captionsSchema pour les composants qui acceptent des sous-titres.
Pour les composants qui acceptent des enfants React.ReactNode, ajoutez ...Interactive.childrenSchema.
Il fournit des contrôles pour le contenu des enfants et peut évoluer pour supporter un contenu plus riche.
Actuellement, il utilise un champ de chaîne de caractères étiqueté "Texte" avec une valeur par défaut de ''.
Si un composant nécessite des enfants uniquement sous forme de chaînes, déclarez un champ children explicite avec type: 'string' à la place.
Interactive.textSchema contrôle les styles typographiques ; childrenSchema contrôle le contenu.
Le fragment enfants n'est pas inclus dans baseSchema ou automatiquement ajouté aux composants personnalisés.
Le balisage imbriqué et les enfants calculés sont actuellement en lecture seule.
text-content est un alias obsolète pour le type de champ string.
Voir InteractivitySchema pour toutes les options.
Enregistrer les composants réutilisables en tant que compositions connectées
Enregistrez les scènes et les éléments réutilisables en tant que compositions autonomes. Le Studio appelle ces compositions connectées : elles peuvent être ouvertes dans leur propre timeline tout en partageant la même implémentation de composant que la vidéo parente.
Définissez les styles requis et chargez les polices à l'intérieur du composant pour qu'il fonctionne sans son parent. Voir l'indépendance parente.
Enregistrez la même référence de composant exporté que le parent affiche. Pour l'exemple
ci-dessus, utilisez component={Chapter}, pas ChapterInner ou un wrapper en ligne.
Interactive.create() fournit la séquence, donc aucun <Sequence> supplémentaire n'est nécessaire pour la connexion.
import {Composition} from 'remotion';
import {Chapter} from './Chapter';
export const RemotionRoot = () => (
<Composition
id="Chapter"
component={Chapter}
width={1280}
height={720}
fps={30}
durationInFrames={90}
defaultProps={{
title: 'Une nouvelle perspective',
style: {
backgroundColor: '#111111',
justifyContent: 'center',
alignItems: 'center',
},
}}
/>
);
Choisissez un ID unique, des valeurs par défaut en ligne représentatives, ainsi que des dimensions, des fps et une durée adaptés à la prévisualisation du composant. Les valeurs par défaut d'enregistrement ne copient pas automatiquement les propriétés d'une instance parente. Voir compositions connectées pour les détails d'enregistrement et d'extraction.
Placer le minutage directement sur le composant
Évitez un <Sequence> séparé autour d'un composant qui accepte déjà les propriétés de minutage.
Les composants interactifs intégrés et les composants personnalisés créés avec
Interactive.create() peuvent recevoir name, from, durationInFrames,
trimBefore, et playbackRate directement.
<Chapter
name="Scène d'ouverture"
from={30}
durationInFrames={90}
style={{opacity: 0.9}}
title="Une nouvelle perspective"
/>
Pour le minutage partagé des scènes, regroupez le contenu dans un composant créé avec
Interactive.create() et chronométrez cette instance. Les racines gérées acceptent également
width et height pour useVideoConfig().
Utilisez <Track> pour placer des éléments sur la même ligne de timeline du Studio.
Utilisez <TransitionSeries> lorsque les scènes sont séquentielles.
Donner à chaque élément modifiable indépendamment son propre nœud JSX
Le Studio modifie le nœud source JSX qui a créé un élément. Si plusieurs éléments d'exécution proviennent du même nœud JSX, ils partagent une seule cible d'édition source.
Pour chaque enregistrement de composition, clip, scène, calque ou séquence qui doit
être modifiable par lui-même, écrivez un nœud JSX séparé et conservez ses propriétés modifiables
sur ce nœud. Cela s'applique à <Composition>, <Still>, les composants média
intégrés, <Sequence>, <TransitionSeries.Sequence>
et les composants personnalisés.
Par exemple, créez une timeline modifiable comme ceci :
import { Track } from "remotion";
<Track name="Scènes">
<Introduction name="Introduction" durationInFrames={90} />
<Demo name="Démo" from={90} durationInFrames={150} />
</Track>
Un .map() ou une autre boucle programmatique créerait plusieurs éléments d'exécution
à partir d'un seul nœud source JSX. Cela est approprié pour une sortie répétée qui est
intentionnellement contrôlée comme un modèle unique, comme des barres de visualisation ou des
particules. Ce n'est pas approprié lorsque les instances nécessitent des ID ou des noms,
des propriétés, des métadonnées, un minutage, un ordre, une suppression ou une duplication
indépendants dans le Studio.
Rendre un élément HTML interactif avec Interactive
Chaque élément HTML et SVG (sauf <Img>, qui est déjà interactif) comme <div> peut être rendu interactif en utilisant Interactive :
<Interactive.Div
name="Carte de vœux"
style={{fontSize: 80, padding: 24}}
>
Bonjour
</Interactive.Div>
Cela permet de définir les styles et les images clés dans le Studio. Soyez raisonnable, si un composant a de nombreux éléments, la timeline peut devenir désordonnée.
Préférer le texte en ligne
Si le texte est fixe et utilisé une seule fois, écrivez-le directement à l'intérieur de l'élément interactif au lieu de l'extraire dans une constante.
// 👍 Le texte fixe reste modifiable
<Interactive.Div name="Titre">
Bonnes pratiques Remotion
</Interactive.Div>
Utilisez une propriété ou une variable uniquement lorsque le texte est dynamique ou réutilisé.
Donner aux éléments interactifs un nom descriptif
Ajoutez une propriété name aux éléments pour les rendre facilement identifiables.
Évitez les noms calculés, codez-les en dur.
<>
<Interactive.Div name="Titre Héros" style={{fontSize: 80}}>
Jour du lancement
</Interactive.Div>
<Img name="Avatar" src="https://remotion.media/image.jpeg" />
<Video name="Arrière-plan" src="https://remotion.media/video.mp4" />
<Interactive.Div name="Titre">
Jour du lancement
</Interactive.Div>
</>
Garder tous les styles CSS en ligne
La meilleure façon est de simplement passer un objet simple à style - pas de référence à des constantes, pas de déploiement d'objet, pas de calcul.
<Interactive.Div
style={{
fontSize: 80,
color: 'red',
}}
>
Bonjour le monde !
</Interactive.Div>
const baseStyle = useMemo(() => {
return {
fontSize: 12 // ❌ Les styles non en ligne ne sont pas pris en charge
}
}, []);
<Interactive.Div
style={{
...baseStyle, // ❌ Le déploiement n'est pas pris en charge
color: RED, // ❌ La référence à des constantes n'est pas prise en charge
scale: frame * 10 // ❌ Le calcul n'est pas pris en charge
}}
>
Bonjour le monde !
</Interactive.Div>
Animer avec interpolate()
Écrivez les animations comme des appels interpolate() en ligne sur la propriété qui change.
La plage de sortie, l'interpolation, l'extrapolation et la propriété output doivent utiliser des valeurs codées en dur.
La plage d'entrée peut également utiliser durationInFrames, fps, width et height déstructurés directement depuis useVideoConfig(). Les identifiants simples tels que durationInFrames, la multiplication par un nombre tel que 2 * fps ou fps * 2, et la soustraction d'un nombre tel que durationInFrames - 1 sont pris en charge.
const {fps, durationInFrames} = useVideoConfig();
// 👍 Les valeurs en ligne peuvent être standardisées et animées par images clés
<Interactive.Div
name="Carte produit"
style={{
color: 'white',
fontSize: 80,
scale: interpolate(frame, [0, fps], [0, 1], {
easing: Easing.spring({damping: 200}),
output: 'perceptual-scale',
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp'
}),
rotate: interpolate(frame, [0, 1 * fps], ['0deg', '20deg'], {
easing: Easing.spring({damping: 200}),
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp'
}),
translate: interpolate(
frame,
[durationInFrames - 30, durationInFrames],
['0px 0px', '0px 120px'],
{
easing: Easing.spring({damping: 200}),
output: 'perceptual-scale',
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp'
}
),
}}
/>
const translateY = interpolate(frame, [0, 30], [0, 120]); // ❌ Le calcul devrait être directement dans le balisage
<Interactive.Div
name="Carte produit"
style={{
translate: translateY, // ❌ Seuls les appels interpolate() en ligne sont pris en charge,
rotate: interpolate(frame, [start, start + 10], [0, Math.PI]), // ❌ Impossible d'utiliser des calculs avec des variables arbitraires, impossible d'utiliser des constantes
scale: interpolate(anyVariable, [0, 30], [0, 1]) // ❌ Peut uniquement interpréter la variable `frame`.
}}
/>
Garder les chemins SVG modifiables avec Interactive.Path
Utilisez <Interactive.Path> de remotion au lieu de <path> à l'intérieur d'un SVG pour rendre le chemin visuellement modifiable.
Installez @remotion/paths pour l'interpolation de chemin et les images clés de chemin Studio :
bunx remotion add @remotion/paths
Si la géométrie est destinée à être statique, placez la chaîne de chemin directement dans la propriété d. Ne l'extrayez pas dans une constante.
import {Interactive} from 'remotion';
<Interactive.Svg width={300} height={300} viewBox="0 0 300 300">
<Interactive.Path
name="Triangle"
d="M 40 40 L 260 40 L 150 260 Z"
fill="#0b84f3"
/>
</Interactive.Svg>
Morphing de chemins en utilisant inl
…
