diff --git a/.claude/skills/remotion-video/SKILL.md b/.claude/skills/remotion-video/SKILL.md new file mode 100644 index 0000000..754c137 --- /dev/null +++ b/.claude/skills/remotion-video/SKILL.md @@ -0,0 +1,84 @@ +--- +name: remotion-video +description: Create videos from React code with Remotion. Use when the user asks to make, animate, preview, or render a video, motion graphic, intro, caption, or social clip using code. +--- + +# Remotion Video + +Remotion makes videos out of React components. Each frame is a web page. Render them in order and you get an MP4. + +## Core ideas +- **Composition**: one video. Has `width`, `height`, `fps`, `durationInFrames`. +- **Frame**: `useCurrentFrame()` returns the current frame number. All animation is a function of the frame. +- **`interpolate`**: maps a frame range to a value range (fade, slide). +- **`spring`**: natural bouncy motion. +- **`Sequence`**: shows children only during a frame range. +- **`AbsoluteFill`**: full-screen layer; stack them for backgrounds. +- **`Audio` / `OffthreadVideo` / `Img`**: media. Put files in `public/` and load with `staticFile("name.mp3")`. + +## Workflow +1. **Plan first.** Ask or decide: length (seconds), size (1920x1080, or 1080x1920 for vertical), fps (30), and the scenes. Keep scenes to a short list. +2. **Set up** (skip if the project exists): + ``` + npx create-video@latest + cd && npm install + ``` +3. **Write** compositions in `src/`, register them in `src/Root.tsx`. +4. **Preview**: `npm run dev` (opens Remotion Studio). +5. **Render**: `npx remotion render out/video.mp4` + Still frame: `npx remotion still out/frame.png --frame=30` +6. **Verify**: render one still first, check it looks right, then render the full video. + +## Starter example +`src/Root.tsx` +```tsx +import { Composition } from "remotion"; +import { Hello } from "./Hello"; + +export const RemotionRoot = () => ( + +); +``` + +`src/Hello.tsx` +```tsx +import { AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion"; + +export const Hello = ({ title }: { title: string }) => { + const frame = useCurrentFrame(); + const { fps } = useVideoConfig(); + const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" }); + const scale = spring({ frame, fps, config: { damping: 12 } }); + + return ( + +

{title}

+
+ ); +}; +``` + +## Rules of thumb +- Never animate with CSS transitions, `setTimeout`, or CSS animations. They don't render per frame. Drive everything from `useCurrentFrame()`. +- Always pass `extrapolateRight: "clamp"` to `interpolate` unless you want values to keep growing. +- Seconds to frames: `seconds * fps`. +- Use `` to order scenes; `` to chain them. +- Load fonts with `@remotion/google-fonts` so they are ready before rendering. +- Keep props in `defaultProps` so the user can edit text in the Studio. +- Rendering needs Chromium and ffmpeg (Remotion installs/handles these); first render can be slow. + +## Common problems +- **Blank/white frames**: an asset path is wrong; use `staticFile()`. +- **Flicker**: an image or font not loaded; use `` and `@remotion/google-fonts`. +- **Slow render**: lower resolution/fps while testing, or use `--concurrency`. + +## Docs +https://www.remotion.dev/docs