Esta es una guía para escribir marcado React de Remotion. Si esto no es relevante, carga Mejores Prácticas de Remotion en su lugar.
Conservar cambios del usuario
Los usuarios pueden hacer ediciones en el código fuera de la conversación.
Si detectas un cambio sorprendente realizado mientras tanto, no lo sobrescribas, asume que fue intencional o pide confirmación.
Reglas generales
Dentro de un componente de composición o escena, obtén fps de useVideoConfig() para todos los cálculos de segundos a fotogramas, incluyendo propiedades de temporización como from, trimBefore, durationInFrames y premountFor. Mantener la expresión en el nodo JSX, como trimBefore={4 * fps}, permite que el Estudio edite la temporización y la mantenga correcta si la velocidad de fotogramas de la composición cambia.
Impulsa las animaciones usando useCurrentFrame() e interpolate().
Las transiciones o animaciones CSS no se renderizarán correctamente; deben ser refactorizadas.
Las clases de animación de Tailwind no se renderizarán correctamente; deben ser refactorizadas.
Usa Easing.bezier() y Easing.spring() para personalizar la temporización.
Estructura tu marcado de acuerdo con las Mejores Prácticas de Interactividad de Remotion.
Prefiere Interactive.withSchema({wrapInSequence: true, layout: 'absolute-fill'}) para escenas con propiedades editables. Su marcado interno puede devolver un fragmento; el envoltorio maneja el diseño y los estilos de la instancia. Los elementos dimensionados, como los tercios inferiores, pueden mantener el diseño predeterminado y pasar style a su propia raíz. Registra las escenas reutilizables como composiciones conectadas.
Coloca la temporización directamente en los componentes que la soporten; evita envoltorios redundantes <Sequence>.
Asigna a cada componente temporizado que soporte premountFor un segundo de pre-montaje: premountFor={fps}, donde fps proviene de useVideoConfig(). Aplica esto a medios, componentes interactivos, <Sequence>, <TransitionSeries.Sequence> y <TransitionSeries.Overlay>, incluyendo componentes temporizados anidados dentro de escenas. También premonta el elemento de la línea de tiempo padre cuando un elemento anidado necesita montarse antes de que el padre comience. Un componente sin premountFor, como <TransitionSeries.Transition>, no necesita sustituto.
El Estudio edita el nodo fuente JSX que creó un elemento. Crea cada registro de composición, clip, escena, capa y secuencia que deba ser editable de forma independiente como su propio nodo JSX, con sus propiedades editables en línea. Los bucles programáticos son adecuados cuando las instancias generadas se controlan intencionalmente como una plantilla fuente única, no cuando los usuarios necesitan editar las instancias por separado.
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>
);
};
Mantén la llamada interpolate() en línea dentro de la propiedad style.
Usa las propiedades CSS scale, translate, rotate en lugar de transform.
// 👍 Fotogramas clave editables en línea y abreviaturas de transformación
style={{
scale: interpolate(frame, [0, 100], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.spring({damping: 200}),
output: 'perceptual-scale' // Para animaciones de `scale`, usa "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}),
}),
}}
// 👎 Los valores fuera de línea y las cadenas de transformación son más difíciles de editar en el Estudio
const scale = interpolate(frame, [0, 100], [0, 1]);
style={{
transform: `scale(${scale})`,
}}
Activos
Coloca los activos en la carpeta public/ en la raíz de tu proyecto.
Usa staticFile() para hacer referencia a archivos de la carpeta public/.
Componentes multimedia
Agrega video y audio usando <Video> y <Audio> de @remotion/media.
Agrega imágenes usando el componente <CanvasImage>.
Agrega GIFs animados, APNG, WebP o imágenes AVIF usando <AnimatedImage>, usa @remotion/gif si no usas Chrome.
Usa staticFile() para archivos en public/ o pasa una URL remota directamente:
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 composición es principalmente una línea de tiempo de clips de video o audio, lee video-editing.md antes de elegir su estructura fuente.
Escena de ejemplo
Un video de fondo con un tercio inferior.
El tercio inferior es un componente interactivo con su propia línea de tiempo, registrado como una composición conectada.
Su texto se pasa como children y accentColor es una propiedad editable.
La aparición gradual está animada en el lugar de la llamada.
// 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: "Color de acento",
},
} 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",
}}
/>
</>
);
};
Retardo, recorte
Coloca la temporización directamente en los componentes que la soporten. Consulta Propiedades de temporización para las propiedades soportadas, ejemplos y orden de operaciones.
Mapas
Consulta Mapas de Remotion si deseas incluir mapas en el video.
Resaltados y anotaciones de texto
Consulta resaltados-de-texto.md para resaltados de texto (marcadores de resaltado), círculos, subrayados, tachados, texto tachado, recuadros.
Videos de múltiples escenas
Consulta video-de-multiples-escenas.md si planeas hacer un video con múltiples escenas consecutivas.
Composiciones conectadas
Cuando una escena o grupo de capas merece su propia línea de tiempo editable, sigue composiciones-conectadas.md. Prefiere esta estructura para escenas sustanciales en un video de múltiples escenas.
Acción de pre-composición
Para una solicitud del Estudio como Pre-componer Resplandor ambiente (src/BarChart.tsx:134), encuentra el marcado de la secuencia seleccionada en la ubicación dada. Crea una composición conectada, siguiendo composiciones-conectadas.md: extrae el marcado en un componente nombrado, preferiblemente hazlo interactivo con Interactive.withSchema({wrapInSequence: true}), y registra la misma referencia de componente exportada con una <Composition> única en la raíz. Renderiza el componente interactivo directamente con sus propiedades de temporización, o como el único hijo de una secuencia cuando ese envoltorio tenga un propósito. Si el nodo seleccionado ya es una secuencia, mantén sus propiedades y extrae sus hijos. El registro necesita dimensiones, fps, duración y defaultProps equivalentes a su uso padre. Una extracción de componente sin una composición registrada no completa una solicitud de pre-composición.
Lleva los estilos heredados como fontFamily y la carga de fuentes al componente extraído; consulta independencia del padre.
Voz en off
Consulta voz-en-off.md para agregar una voz en off generada por IA a las composiciones de Remotion usando ElevenLabs TTS.
Incrustación de videos
Consulta incrustacion-de-videos.md para conocimiento avanzado sobre incrustación de videos: recorte, volumen, velocidad, bucle, tono.
Incrustación de audio
Consulta audio.md para funciones avanzadas de audio como recorte, volumen, velocidad, tono.
Recorte
Consulta recorte.md si necesitas recortar el rectángulo visible de un componente.
Transiciones
Consulta transiciones.md para patrones de transición de escenas.
Desenfoque de movimiento
Al agregar desenfoque de movimiento o una estela de movimiento, lee desenfoque-de-movimiento.md para conocer el enfoque preferido de HTML en canvas, requisitos de vista previa y alternativas.
Efectos visuales y de píxeles
Al agregar un efecto visual, primero identifica el elemento o grupo sobre el que debería actuar.
Si el componente objetivo soporta effects y un efecto incorporado a continuación coincide con la solicitud, prefiere ese efecto sobre una aproximación CSS. Por ejemplo, aplica vignette() directamente a la propiedad effects de un <Video> cuando la viñeta deba afectar a ese video.
Estos componentes aceptan effects directamente:
| Importar de | Componentes |
|---|---|
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> |
Los elementos HTML ordinarios, los envoltorios DOM <Interactive.*>, <AbsoluteFill> y <Sequence> no aceptan effects directamente. Para aplicar efectos a su contenido, envuélvelos en <HtmlInCanvas> y coloca la propiedad effects en el envoltorio.
Para otros elementos, prefiere HTML y CSS regulares cuando sea adecuado. Considera envolver un grupo en <HtmlInCanvas> cuando el post-procesamiento de todo el grupo sea apropiado y el entorno lo soporte.
Lee efectos.md antes de aplicar un efecto para importaciones, parámetros y configuración. También cubre efectos personalizados reutilizables con createEffect() cuando ningún efecto incorporado coincida.
Efectos disponibles
Efectos incorporados de @remotion/effects:
- Color y tono:
brightness(),colorCorrection(),colorKey(),contrast(),duotone(),exposure(),grayscale(),hue(),invert(),levels(),linearGradient(),linearGradientTint(),lut(),saturation(),shadowsHighlights(),thermalVision(),tint(),vibrance(),whiteBalance(). - Desenfoque y estelas:
blur(),lightTrail(),linearProgressiveBlur(),radialProgressiveBlur(),regionBlur(),trail(),vignette(),wind(). - Dispersión y distorsión:
circle(),curl(),displacementMap(),fadeToColor(),hexagonalPixelate(),julia(),noise(),pixelate(),posterize(),selectiveColorBlur(),solidColor(),wave(). - Arte y efectos especiales:
chromaKey(),crt(),dots(),edgeWork(),emboss(),glitch(),glow(),kaleidoscope(),mirror(),oil(),outline(),rembrandt(),sepia(),sketch(),toon(),transparent(),vignetteBlur().
Consulta efectos.md para más detalles sobre estos efectos.