Remotion LabRemotion Lab
入門元件重用與 Sequence

元件重用與 Sequence

學會用 React 元件封裝動畫、用 Sequence 控制時序,讓影片專案更好維護。

為什麼要元件化?

當影片變得複雜,把所有邏輯塞在一個檔案裡會變得難以維護。好消息是——Remotion 的影片就是 React 元件,所以你可以用 React 的方式來組織程式碼。

封裝可重用的動畫元件

假設你要做一個片頭,裡面有標題和副標題。先把「淡入」這個行為封裝成元件:

import { useCurrentFrame, interpolate } from "remotion";
 
interface FadeInProps {
  children: React.ReactNode;
  delay?: number;
}
 
export const FadeIn: React.FC<FadeInProps> = ({ children, delay = 0 }) => {
  const frame = useCurrentFrame();
 
  const opacity = interpolate(frame - delay, [0, 20], [0, 1], {
    extrapolateLeft: "clamp",
    extrapolateRight: "clamp",
  });
 
  return <div style={{ opacity }}>{children}</div>;
};

現在你可以在任何地方重複使用:

<FadeIn>第一段文字</FadeIn>
<FadeIn delay={15}>第二段文字</FadeIn>
<FadeIn delay={30}>第三段文字</FadeIn>

用 Sequence 控制時序

<Sequence> 是 Remotion 的時序控制元件。它讓你指定「這段內容從第幾幀開始出現」:

import { AbsoluteFill, Sequence } from "remotion";
 
export const MyVideo: React.FC = () => {
  return (
    <AbsoluteFill style={{ backgroundColor: "#1a1a2e" }}>
      <Sequence from={0} durationInFrames={60}>
        <Title text="歡迎" />
      </Sequence>
 
      <Sequence from={30} durationInFrames={60}>
        <Subtitle text="這是一個 Remotion 影片" />
      </Sequence>
 
      <Sequence from={60}>
        <CallToAction text="立即開始" />
      </Sequence>
    </AbsoluteFill>
  );
};

重點:<Sequence> 內的元件,useCurrentFrame() 會從 0 開始計算。也就是說,Title 元件不需要知道自己是從整支影片的第幾幀開始——它只需要關心自己的動畫邏輯。這就是 Sequence 強大的地方。

用 Props 驅動配置

既然影片是 React 元件,你當然可以用 Props 來驅動:

interface IntroProps {
  title: string;
  subtitle: string;
  accentColor: string;
}
 
export const Intro: React.FC<IntroProps> = ({
  title,
  subtitle,
  accentColor,
}) => {
  return (
    <AbsoluteFill
      style={{
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#0f0f1a",
      }}
    >
      <Sequence from={0} durationInFrames={60}>
        <FadeIn>
          <h1 style={{ color: accentColor, fontSize: 72 }}>{title}</h1>
        </FadeIn>
      </Sequence>
 
      <Sequence from={20} durationInFrames={60}>
        <FadeIn>
          <p style={{ color: "white", fontSize: 36 }}>{subtitle}</p>
        </FadeIn>
      </Sequence>
    </AbsoluteFill>
  );
};

在 Composition 裡使用:

<Composition
  id="Intro"
  component={Intro}
  durationInFrames={90}
  fps={30}
  width={1920}
  height={1080}
  defaultProps={{
    title: "我的頻道",
    subtitle: "每週更新",
    accentColor: "#00d4ff",
  }}
/>

改一下 Props,就能產出不同版本的片頭——這就是程式化影片的威力。

完整範例:一個片頭動畫

結合以上所有概念,做一個完整的片頭:

import {
  AbsoluteFill,
  Sequence,
  useCurrentFrame,
  useVideoConfig,
  spring,
  interpolate,
} from "remotion";
 
const AnimatedText: React.FC<{ text: string; fontSize: number }> = ({
  text,
  fontSize,
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
 
  const progress = spring({ frame, fps, config: { damping: 12 } });
  const translateY = interpolate(progress, [0, 1], [40, 0]);
  const opacity = interpolate(progress, [0, 0.5], [0, 1], {
    extrapolateRight: "clamp",
  });
 
  return (
    <div
      style={{
        transform: `translateY(${translateY}px)`,
        opacity,
        fontSize,
        color: "white",
        fontWeight: "bold",
        textAlign: "center",
      }}
    >
      {text}
    </div>
  );
};
 
export const OpeningSequence: React.FC = () => {
  return (
    <AbsoluteFill
      style={{
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#0f0f1a",
      }}
    >
      <Sequence from={0} durationInFrames={60}>
        <AnimatedText text="Remotion 社群" fontSize={80} />
      </Sequence>
 
      <Sequence from={20} durationInFrames={60}>
        <AnimatedText text="用程式碼創作影片" fontSize={36} />
      </Sequence>
 
      <Sequence from={45} durationInFrames={45}>
        <AnimatedText text="立即開始 →" fontSize={28} />
      </Sequence>
    </AbsoluteFill>
  );
};

小結

  • 封裝元件 — 把動畫邏輯封裝成可重用的 React 元件。
  • Sequence 控制時序 — 用 <Sequence> 安排每段內容的出場時間,內部的 useCurrentFrame() 會自動歸零。
  • Props 驅動 — 用 Props 讓同一個元件產出不同內容,實現批量化影片製作。

掌握這三個模式,你就能打造結構清晰、容易維護的 Remotion 影片專案。