Skip to content

Instantly share code, notes, and snippets.

@chan-ume
Created February 19, 2026 05:38
Show Gist options
  • Select an option

  • Save chan-ume/2bd57a79fe1aec803d3d6a0079e34eb3 to your computer and use it in GitHub Desktop.

Select an option

Save chan-ume/2bd57a79fe1aec803d3d6a0079e34eb3 to your computer and use it in GitHub Desktop.
Remotion でトランジションを作る実装例
// https://www.randpy.tokyo/entry/remotion-6-transition
import { AbsoluteFill, Sequence, Series, spring, useCurrentFrame, useVideoConfig } from "remotion";
import { TransitionSeries, linearTiming, springTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
import { slide } from "@remotion/transitions/slide";
import { wipe } from "@remotion/transitions/wipe";
import { z } from "zod";
import { zColor } from "@remotion/zod-types";
const ColorScene: React.FC<{
color: string;
title: string;
subtitle?: string;
}> = ({ color, title, subtitle }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const scale = spring({ frame, fps, config: { damping: 100 } });
return (
<AbsoluteFill
style={{
backgroundColor: color,
justifyContent: "center",
alignItems: "center",
}}
>
<div style={{ transform: `scale(${scale})`, textAlign: "center" }}>
<div
style={{
fontSize: 80,
fontWeight: "bold",
color: "white",
fontFamily: "sans-serif",
textShadow: "0 2px 12px rgba(0,0,0,0.3)",
}}
>
{title}
</div>
{subtitle && (
<div
style={{
fontSize: 32,
color: "rgba(255,255,255,0.8)",
fontFamily: "monospace",
marginTop: 16,
}}
>
{subtitle}
</div>
)}
</div>
</AbsoluteFill>
);
};
export const scenesDemoSchema = z.object({
sceneAColor: zColor(),
sceneBColor: zColor(),
sceneCColor: zColor(),
transitionDuration: z.number(),
});
// --- Phase 1: Series ショーケース ---
const SeriesShowcase: React.FC<{
sceneAColor: string;
sceneBColor: string;
sceneCColor: string;
}> = ({ sceneAColor, sceneBColor, sceneCColor }) => {
return (
<AbsoluteFill>
{/* Series ラベル */}
<AbsoluteFill style={{ zIndex: 10 }}>
<div
style={{
position: "absolute",
top: 30,
left: 40,
backgroundColor: "rgba(0,0,0,0.7)",
color: "white",
fontSize: 28,
fontFamily: "monospace",
padding: "8px 16px",
borderRadius: 8,
}}
>
{"<Series>"}
</div>
</AbsoluteFill>
<Series>
<Series.Sequence durationInFrames={60}>
<ColorScene
color={sceneAColor}
title="Scene A"
subtitle="durationInFrames={60}"
/>
</Series.Sequence>
<Series.Sequence durationInFrames={60}>
<ColorScene
color={sceneBColor}
title="Scene B"
subtitle="durationInFrames={60}"
/>
</Series.Sequence>
<Series.Sequence durationInFrames={60}>
<ColorScene
color={sceneCColor}
title="Scene C"
subtitle="durationInFrames={60}"
/>
</Series.Sequence>
</Series>
</AbsoluteFill>
);
};
// --- Phase 2: TransitionSeries ショーケース ---
const TransitionShowcase: React.FC<{
transitionDuration: number;
}> = ({ transitionDuration }) => {
return (
<AbsoluteFill>
{/* TransitionSeries ラベル */}
<AbsoluteFill style={{ zIndex: 10 }}>
<div
style={{
position: "absolute",
top: 30,
left: 40,
backgroundColor: "rgba(0,0,0,0.7)",
color: "white",
fontSize: 28,
fontFamily: "monospace",
padding: "8px 16px",
borderRadius: 8,
}}
>
{"<TransitionSeries>"}
</div>
</AbsoluteFill>
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60}>
<ColorScene color="#8b5cf6" title="fade()" subtitle="linearTiming" />
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={fade()}
timing={linearTiming({ durationInFrames: transitionDuration })}
/>
<TransitionSeries.Sequence durationInFrames={60}>
<ColorScene
color="#0891b2"
title="slide()"
subtitle='direction: "from-left"'
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={slide({ direction: "from-left" })}
timing={springTiming({ config: { damping: 200 } })}
/>
<TransitionSeries.Sequence durationInFrames={60}>
<ColorScene
color="#ea580c"
title="wipe()"
subtitle='direction: "from-left"'
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={wipe({ direction: "from-left" })}
timing={linearTiming({ durationInFrames: transitionDuration })}
/>
<TransitionSeries.Sequence durationInFrames={60}>
<ColorScene color="#16a34a" title="Done!" subtitle="springTiming" />
</TransitionSeries.Sequence>
</TransitionSeries>
</AbsoluteFill>
);
};
// --- メインコンポーネント ---
export const ScenesDemo: React.FC<z.infer<typeof scenesDemoSchema>> = ({
sceneAColor,
sceneBColor,
sceneCColor,
transitionDuration,
}) => {
return (
<AbsoluteFill>
<Sequence from={0} durationInFrames={180}>
<SeriesShowcase
sceneAColor={sceneAColor}
sceneBColor={sceneBColor}
sceneCColor={sceneCColor}
/>
</Sequence>
<Sequence from={180} durationInFrames={180}>
<TransitionShowcase transitionDuration={transitionDuration} />
</Sequence>
</AbsoluteFill>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment