Remotionでローワーサードとテキストアニメーションを作る完全ガイド
Remotionでローワーサードとテキストアニメーションを作る完全ガイド
ローワーサード、テキストリビール、タイプライター効果は、動画制作で最もよく求められるモーショングラフィックス要素です。従来のNLE(動画編集ソフト)ではタイムライン上で一つひとつ手作業で作りますが、Remotionではそれらを一度Reactコンポーネントとして書いておけば、名前・肩書き・カラーをpropsで差し替えるだけで何度でも再利用できます。
本記事では「アニメーション付きローワーサード」「テキストリビールアニメーション」「タイプライター効果」の3つを、実際に動くコード付きで詳しく解説します。
ローワーサードとは
ローワーサードとは、動画フレームの下部に表示されるテキストオーバーレイです。出演者の名前や肩書きを表示するために使われます。テレビ放送では専用のグラフィックシステムで生成されますが、RemotionではuseCurrentFrame()を読み取るシンプルなReactコンポーネントとして実装できます。
アニメーション付きローワーサードを作る
良いローワーサードは通常3つのフェーズで構成されます。
- イン — スライドやフェードでフレームに登場する
- ホールド — テキストが完全に表示された状態を維持する
- アウト — 次のカットの前にフレームを退出する
interpolateとspringを使った最小実装は次のとおりです。
import {
interpolate,
spring,
useCurrentFrame,
useVideoConfig,
} from "remotion";
interface LowerThirdProps {
name: string;
title: string;
accentColor?: string;
}
export const LowerThird: React.FC<LowerThirdProps> = ({
name,
title,
accentColor = "#e63946",
}) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// 登場時に上方向へスライド
const translateY = spring({
fps,
frame,
config: { damping: 14, stiffness: 120 },
from: 40,
to: 0,
});
// フェードイン
const opacity = interpolate(frame, [0, 12], [0, 1], {
extrapolateRight: "clamp",
});
// アクセントバーの横幅リビール
const barWidth = interpolate(frame, [0, 20], [0, 6], {
extrapolateRight: "clamp",
});
return (
<div
style={{
position: "absolute",
bottom: 120,
left: 80,
transform: `translateY(${translateY}px)`,
opacity,
display: "flex",
alignItems: "center",
gap: 16,
fontFamily: '"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif',
}}
>
{/* カラーアクセントバー */}
<div
style={{
width: barWidth,
height: 56,
background: accentColor,
borderRadius: 2,
}}
/>
<div>
<div
style={{
color: "#ffffff",
fontSize: 28,
fontWeight: 700,
letterSpacing: 0.5,
}}
>
{name}
</div>
<div
style={{
color: "rgba(255,255,255,0.75)",
fontSize: 18,
fontWeight: 400,
}}
>
{title}
</div>
</div>
</div>
);
};
シーンにローワーサードを組み込む
<Sequence>でラップして表示タイミングを制御します。
import { Sequence } from "remotion";
import { LowerThird } from "./LowerThird";
export const InterviewScene: React.FC = () => (
<>
{/* フレーム30〜150の間だけ表示 */}
<Sequence from={30} durationInFrames={120}>
<LowerThird name="石野宏実" title="Trimora株式会社 代表取締役" />
</Sequence>
</>
);
テキストリビールアニメーション
テキストリビールは、単語や文字を順番に表示するアニメーションです。代表的なスタイルはフェードアップ(単語が下から順番に浮かび上がる)とワイプ(テキストが左からスライドして現れる)の2種類です。
単語ごとのフェードアップ
import { interpolate, useCurrentFrame } from "remotion";
interface WordRevealProps {
text: string;
startFrame?: number;
staggerFrames?: number;
}
export const WordReveal: React.FC<WordRevealProps> = ({
text,
startFrame = 0,
staggerFrames = 6,
}) => {
const frame = useCurrentFrame();
// 日本語はスペース区切りではなく文字単位で処理するほうが自然
const words = text.split(/(\s+)/).filter(Boolean);
return (
<div
style={{
display: "flex",
flexWrap: "wrap",
gap: 4,
fontFamily: '"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif',
fontSize: 56,
fontWeight: 700,
color: "#fff",
}}
>
{words.map((word, i) => {
const wordFrame = startFrame + i * staggerFrames;
const progress = interpolate(frame, [wordFrame, wordFrame + 15], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
return (
<span
key={i}
style={{
opacity: progress,
transform: `translateY(${(1 - progress) * 24}px)`,
display: "inline-block",
}}
>
{word}
</span>
);
})}
</div>
);
};
タイプライター効果
タイプライター効果はキーボード入力をリアルタイムで打っているように見せるアニメーションです。フレーム番号から文字インデックスを計算し、文字列をスライスして表示します。
import { interpolate, useCurrentFrame } from "remotion";
interface TypewriterProps {
text: string;
durationInFrames?: number;
cursorVisible?: boolean;
}
export const Typewriter: React.FC<TypewriterProps> = ({
text,
durationInFrames = 90,
cursorVisible = true,
}) => {
const frame = useCurrentFrame();
const characterIndex = Math.floor(
interpolate(frame, [0, durationInFrames], [0, text.length], {
extrapolateRight: "clamp",
})
);
const showCursor = cursorVisible && frame % 30 < 15;
return (
<div
style={{
fontFamily: '"Yu Gothic", "Hiragino Kaku Gothic ProN", monospace',
fontSize: 48,
color: "#e2e8f0",
whiteSpace: "pre",
}}
>
{text.slice(0, characterIndex)}
{showCursor && <span>|</span>}
</div>
);
};
日本語テキストに使う場合は、durationInFramesを文字数×2〜3フレーム程度に設定するとちょうど良いタイピング速度になります。
パフォーマンスについて
テキストアニメーションはCSSトランスフォームで実装できるため、画像デコードや動画デコードが発生せず、レンダリング負荷は非常に低いです。複雑な複数レイヤーのローワーサードでも、springアニメーション込みでレンダリングパイプラインへの影響はわずかです。
既製テンプレートを活用すべきシーン
上記のコードは基本的な構成要素を提供するものです。しかし実際の制作現場では、ローワーサードのバリエーションが10種類以上あり、ブランドカラーも複数、アスペクト比も違う、締め切りもある、という状況がほとんどです。ゼロから書くことが重なると工数は急増します。
RenderCompは1,400本以上のRemotionテンプレートの中に、ローワーサードやテキストアニメーションのテンプレートを多数含んでいます。それぞれカラー・フォントサイズ・タイミング・位置などのpropsが編集可能な形で提供されており、受託案件やブランドコンテンツ制作のプロにとって、テンプレートを起点にカスタマイズするほうがほぼ確実に早く仕上がります。
よくある質問(FAQ)
Q: ローワーサードを動画の途中で消すにはどうすればよいですか?
A: 外側の<Sequence>のdurationInFramesを設定します。シーケンスが終了するとコンポーネントはアンマウントされます。フェードアウトを加えたい場合は、useCurrentFrame()でシーケンス終端からの相対フレームを計算してopacityを下げます。
Q: テキストをパスに沿って動かすことはできますか?
A: はい。ReactコンポーネントにSVGの<textPath>要素を使い、startOffset属性の値をinterpolate()で制御することでテキストを曲線に沿って動かせます。
Q: ブランドのフォントをローワーサードに使いたい場合は?
A: @remotion/fontsを使うか、フォントファイルを静的アセットとしてプロジェクトにインポートします。外部CDNからのフォント読み込みは避け、ローカルのフォントファイルを使うことでオフライン環境でも再現性が保たれます。
Q: 日本語・中国語・韓国語テキストのアニメーションはどう処理しますか?
A: CJKフォントを含むシステムフォントスタック(例:"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif)を使います。文字単位のアニメーションも問題なく動作しますが、日本語はスペースで単語分割できないため、文字配列をmapして1文字ずつ処理するほうが自然です。
Q: バリアブルフォントのウェイトをアニメーションできますか?
A: はい。font-variation-settingsスタイルpropsを渡し、ウェイト軸の値をinterpolate()で動的に変化させます。
Q: 透明背景でローワーサードだけを書き出すにはどうすればよいですか?
A: npx remotion render --codec=prores-4444または--codec=vp8/vp9に--transparentフラグを加えることでアルファチャンネル付き動画が出力され、任意のNLEで合成できます。
Q: 実際の映像の上にローワーサードをプレビューする方法は?
A: Remotionの<Video>または<OffthreadVideo>コンポーネントでバッグラウンドクリップをコンポジションに配置し、その上にローワーサードを重ねます。Remotion Studioで確認できます。
まとめ
Remotionにおけるローワーサードとテキストアニメーションは、他のすべてのモーショングラフィックス要素と同じパターンです。「フレーム番号を受け取り、見た目の状態を出力する」。interpolateとspringを使いこなせば、プロの放送制作で見かけるようなテキストアニメーションを、再利用可能・バージョン管理可能なReactコードとして表現できます。
量産・高速納品が求められる現場では、RenderCompのようなテンプレートライブラリを起点にするアプローチが特に有効です。