這是撰寫 Remotion React 標記的指導方針。 若與此無關,請改載入 Remotion 最佳實踐。
保留使用者更動
使用者可能會在對話之外的程式碼中進行編輯。
若你發現在此期間有意外更改,請勿覆寫,應視為有意為之或要求確認。
一般規則
使用 useCurrentFrame() 和 interpolate() 驅動動畫。
CSS transition 或 animation 無法正確渲染,需要重構。
Tailwind 動畫類別無法正確渲染,需要重構。
使用 Easing.bezier() 和 Easing.spring() 自訂時間曲線。
根據 Remotion 互動性最佳實踐來組織您的標記。
import { useCurrentFrame, Easing, interpolate, Interactive } from "remotion";
export const FadeIn = () => {
const frame = useCurrentFrame();
return (
<Interactive.Div
name="Title"
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>
);
};
將 interpolate() 呼叫內聯在 style prop 中。
使用 scale、translate、rotate 等 CSS 屬性而非 transform。
// 👍 內聯可編輯關鍵影格與變形簡寫
style={{
scale: interpolate(frame, [0, 100], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
easing: Easing.spring({damping: 200}),
output: 'perceptual-scale' // 對於 `scale` 動畫,使用 "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}),
}),
}}
// 👎 非內聯數值與變形字串在 Studio 中變得更難編輯
const scale = interpolate(frame, [0, 100], [0, 1]);
style={{
transform: `scale(${scale})`,
}}
資源
將資源放在專案根目錄的 public/ 資料夾中。
使用 staticFile() 來引用 public/ 資料夾中的檔案。
媒體元件
使用 @remotion/media 中的 <Video> 和 <Audio> 加入影片與音訊。
使用 <CanvasImage> 元件加入圖片。
使用 <AnimatedImage> 加入動畫 GIF、APNG、WebP 或 AVIF 圖片;若未使用 Chrome,則使用 @remotion/gif。
使用 staticFile() 處理 public/ 中的檔案,或直接傳入遠端 URL:
import { Audio, Video } from "@remotion/media";
import { staticFile, CanvasImage, AnimatedImage } from "remotion";
export const MyComposition = () => {
return (
<>
<Video src={staticFile("video.mp4")} style={{ opacity: 0.5 }} />
<Audio src={staticFile("audio.mp3")} />
<CanvasImage
src={staticFile("logo.png")}
style={{ width: 100, height: 100 }}
/>
<Video src="https://remotion.media/video.mp4" />
<AnimatedImage src={staticFile('nyancat.gif')} />
</>
);
};
範例場景
import {
AbsoluteFill,
Easing,
Interactive,
interpolate,
useCurrentFrame,
useVideoConfig
} from "remotion";
export const Empty = () => {
const {fps} = useVideoConfig();
const frame = useCurrentFrame();
return (
<AbsoluteFill
name="Scene"
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}}
>
<Interactive.Div
name="Title"
style={{
opacity: interpolate(frame, [1 * fps, 2 * fps], [0, 1], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: Easing.bezier(0.16, 1, 0.3, 1),
}),
fontSize: 88
}}
>
Title
</Interactive.Div>
<Interactive.Div
name="Subtitle"
style={{
opacity: interpolate(frame, [2 * fps, 3 * fps, 8 * fps, 10 * fps], [0, 1, 1, 0], {
extrapolateRight: "clamp",
extrapolateLeft: "clamp",
easing: [Easing.bezier(0.16, 1, 0.3, 1), Easing.linear, Easing.bezier(0.16, 1, 0.3, 1)],
}),
fontSize: 32
}}
>
Subtitle
</Interactive.Div>
</AbsoluteFill>
);
}
延遲與裁剪
大多數元件(<AbsoluteFill>、<Interactive.*>、<Img>、<AnimatedImage>、<CanvasImage>、<HtmlInCanvas>、<Solid>、來自 remotion 的 <Sequence>、來自 @remotion/media 的 <Video> 和 <Audio>、<Gif> 等)支援以下 props:
from
<Img from={1 * fps} {/* ... */}/>
<Video from={1 * fps} {/* ... */}/>
<Interactive.Div from={1 * fps} {/* ... */}/>
元素在時間線上開始出現的時機。
durationInFrames
<Img durationInFrames={20 * fps} {/* ... */}/>
<Interactive.Div durationInFrames={20 * fps} {/* ... */}/>
圖層在時間線上播放的持續時間。
媒體元件則傳入媒體的自然時長:<Video durationInFrames={29.322 * fps}/>
trimBefore
適用於內部時鐘應較晚啟動的元件:
// 裁剪掉影片的前 2 秒
<Video trimBefore={2 * fps} {/* ... */} />
// `useCurrenFrame()` 對子元件從 `10 * fps` 開始
<Sequence trimBefore={10 * fps} {/* ... */} />
退路方案
若某元件不支援這些 props,將其包裹在 remotion 的 <Sequence> 中,該元件具備這些功能。
layout="absolute-fill"讓 Sequence 的行為如同 AbsoluteFilllayout="none"為「無頭」模式,不產生包裝元素。
地圖
若想在影片中納入地圖,請參閱 Remotion 地圖。
文字高亮與註解
文字高亮(高亮標記)、圓圈、底線、刪除線、劃掉文字、框框等,請參閱 text-highlights.md。
多場景影片
若計畫製作包含多個連續場景的影片,請參閱 multi-scene-video.md。
語音旁白
若要為 Remotion 合成添加 AI 生成的語音旁白(使用 ElevenLabs TTS),請參閱 voiceover.md。
嵌入影片
有關嵌入影片的進階知識(裁剪、音量、速度、循環、音調),請參閱 embedding-videos.md。
嵌入音訊
有關音訊的進階功能(裁剪、音量、速度、音調),請參閱 audio.md。
影片編輯
有關在 Remotion Studio 中建構可編輯影片時間線,請參閱 video-editing.md。
裁剪
若需要裁剪元件的可見矩形區域,請參閱 cropping.md。
轉場
場景轉場模式請參閱 transitions.md。
視覺與像素效果
在建立視覺效果時,請考慮是否可行於 CSS 和 HTML,還是需要著色器。
偏好順序:
- 一般 HTML + CSS 或其他網頁技術
- 直接對元件(
<Video>、<Img>)套用效果,或將內容包裹在<HtmlInCanvas>中,該元件也接受effects:- 透過 effects.md 列出的效果
- 當無預設效果可用時,透過 effects.md 自訂
createEffect()
3D 內容
關於使用 Three.js 和 React Three Fiber 在 Remotion 中製作 3D 內容,請參閱 ./3d.md。
音效
需要使用音效時,請載入 ./sfx.md 檔案以取得更多資訊。
音訊視覺化
需要視覺化音訊(頻譜條、波形、低音反應效果)時,請載入 ./audio-visualization.md 檔案以取得更多資訊。
地圖(進階)
關於靜態地圖、動態路線與標記、地理解說、Mapbox、MapLibre、MapTiler、GeoJSON 或 3D 地理飛越,請載入 Remotion 地圖。
字幕
處理字幕時,請載入 Remotion 字幕技能以取得更多資訊。
Google Fonts
這是在 Remotion 中載入字型的推薦方法。請參閱 google-fonts.md 了解如何載入 Google Fonts。
本機字型
有關載入本機字型的方法,請參閱 local-fonts.md。
GIF
有關如何顯示與 Remotion 時間線同步的 GIF,請參閱 gifs.md。
進階圖片
有關影像尺寸與定位、動態影像路徑以及取得影像尺寸,請參閱 images.md。
Lottie 動畫
有關在 Remotion 中嵌入 Lottie 動畫,請參閱 lottie.md。
時間控制
有關 interpolate() 的更多時間控制技巧,請參閱 timing.md。
參數化影片
有關透過 Zod schema 使合成可參數化,請參閱 parameters.md。
測量 DOM 節點
有關在 Remotion 中測量 DOM 元素尺寸,請參閱 measuring-dom-nodes.md。
測量文字
有關測量文字尺寸、將文字適配容器以及檢查溢位,請參閱 measuring-text.md。
使用 FFmpeg
對於某些影片操作(例如修剪影片或偵測靜音),應使用 FFmpeg。請載入 ./ffmpeg.md 檔案以取得更多資訊。
靜音偵測
需要偵測並裁剪影片或音訊檔案中的靜音片段時,請載入 ./silence-detection.md 檔案。
動態時長、尺寸與資料
有關動態設定合成時長、尺寸與 props,請參閱 calculate-metadata.md。
進階合成
有關定義靜態影像、資料夾、預設 props 以及巢狀合成,請參閱 compositions.md。
進階序列
有關更多序列模式(延遲、裁剪、限制項目時長),請參閱 sequencing.md。
安裝模組
使用 npx remotion add 以正確版本新增套件:
npx remotion add @remotion/media
這適用於 @remotion/* 套件、mediabunny、@mediabunny/* 和 zod。
預覽標記
npx remotion studio --no-open
這會啟動一個長時間運行的處理程序,並輸出預覽的伺服器 URL。
若伺服器已啟動,則會輸出該 URL。
您可以透過導覽至 /[composition-id] 來造訪特定合成,例如 http://localhost:3000/MapAnimation。
選擇性:單幀渲染檢查
您可以使用 CLI 渲染單一幀,以快速檢查佈局、顏色或時間。
對於微小編輯、純重構或已從 Studio 或先前的渲染中獲得足夠信心時,可略過此步驟。
npx remotion still [composition-id] --scale=0.25 --frame=30
在 30 fps 下,--frame=30 代表 1 秒處(--frame 從 0 開始算起)。