🎬 Overview — imitating cinema with math
Cinematic templates share a philosophy: every physical camera or post-production effect can be described as a mathematical function of the frame. Camera shake is sin(frame) with decay. Film burn is a radial gradient with varying intensity. Ken Burns is scale + linear translation.
🎯 Three internal categories
- •Camera movement:
camera-shake,whip-pan,ken-burns,zoom-pulse— move the image or create the illusion of lens movement. - •Screen composition:
letterbox-reveal,parallax-pan,spotlight-reveal— control what is visible and how the layers relate to one another. - •Post-production effects:
film-burn,vignette-pulse— overlay texture or shadow layers on the content.
💡 Combine sparingly
Cinematic effects are seasoning — use one or two per scene, not all at once. camera-shake + film-burn at the same moment creates a striking climax. Using the same two effects throughout the video causes visual fatigue.
📳 camera-shake — decaying shake
O camera-shake simulates handheld camera shake: it starts intense and decays exponentially until the movement stops. The core technique is sin(frame) multiplied by an amplitude that decreases with the frame.
const { fps } = useVideoConfig(); // amplitude decai de maxAmp até 0 ao longo do impacto const maxAmp = 18; const decayFrames = fps * 1.5; // 1.5s de tremor const amplitude = interpolate( frame, [0, decayFrames], [maxAmp, 0], { extrapolateRight: "clamp" } ); const shakeX = Math.sin(frame * 1.7) * amplitude; const shakeY = Math.cos(frame * 2.3) * amplitude * 0.6; // aplicar: transform: `translate(${shakeX}px, ${shakeY}px)`
💡 Why use different multipliers for X and Y
The values 1.7 e 2.3 are intentionally not multiples of each other. If they were equal (or one were a multiple of the other), the X and Y cycles would synchronize, creating a visible repeating pattern. Prime or irrational values produce a more organic, chaotic trajectory—similar to real tremors.
Frame 0 — maximum impact
The amplitude is at its peak. The displacement can be ±18px. Use it to simulate an explosion, impact, or abrupt cut.
Intermediate frames — decay
The amplitude decreases linearly via interpolate. The shake persists but weakens, like the vibration after a physical impact fading away.
After decayFrames — stability
extrapolateRight: "clamp" ensures the amplitude doesn't become negative. The camera stops completely and the scene remains stable.
🔥 film-burn — warm light leak
O film-burn overlays orange and yellow light spots that grow and fade in a loop, imitating the light exposure effect on physical film. The spots’ intensity follows a bell curve — they appear out of nowhere, peak in the middle, and disappear.
🌡️ The bell-shaped intensity curve
The peak in the middle creates the feeling that the light “leaks” and then “closes.” Three radial gradients with shifting positions create the organic, unpredictable look of a real film burn.
const totalFrames = fps * 3; // intensidade em sino: 0 → 0.85 → 0 const intensity = interpolate( frame, [0, totalFrames * 0.5, totalFrames], [0, 0.85, 0], { extrapolateRight: "clamp" } ); // posição oscilante para parecer "vazamento" orgânico const xShift1 = 50 + Math.sin(frame * 0.05) * 30;
✓ What to DO
- ✓Use between scenes to hide the cut.
- ✓Combine with noise-grain for the complete old-film look.
- ✓Adjust the maximum intensity (0.85) for a more or less subtle effect.
✗ What NOT to do
- ✗Use in videos with a cool color palette—the warm orange contrasts too much.
- ✗Keep it in a continuous loop — it loses impact after the second occurrence.
- ✗Very high intensity (>0.9) over text — illegible.
🎞️ letterbox-reveal — retracting black bars
O letterbox-reveal starts with black bars covering the top and bottom of the screen — the cinematic 2.35:1 letterbox format — and retracts them over time to reveal the full image. The effect instantly communicates "this is a cinematic moment".
💡 The math behind the bars
Each bar has an initial height that covers ~12% of the screen (the standard 2.35:1 letterbox in 16:9). The spring animates this height down to zero. Because the spring uses clamp, bars never go negative—they just disappear cleanly.
const { height, fps } = useVideoConfig(); const barH = height * 0.12; // 12% = letterbox 2.35:1 const s = spring({ frame, fps, config: { damping: 18, stiffness: 60 } }); // barra superior: começa em barH e vai para 0 const topBarH = interpolate(s, [0, 1], [barH, 0]); // div: position absolute, top: 0, height: topBarH, bg: black
🔦 spotlight-reveal — expanding circle clip-path
O spotlight-reveal uses clip-path: circle() to reveal the content from a central point — like a spotlight opening up. The circle’s radius grows from zero until it covers the entire screen over time.
🔵 CSS circle clip-path
The property clip-path: circle(rPx at xPx yPx) is supported natively and performs well in the browser. In Remotion rendering, it’s rendered via Puppeteer with full support. The radius can be calculated as a percentage of the screen diagonal to ensure full coverage.
const { width, height, fps } = useVideoConfig(); const maxRadius = Math.sqrt(width ** 2 + height ** 2) / 2; const s = spring({ frame, fps, config: { damping: 20, stiffness: 50 } }); const radius = s * maxRadius; // style: clipPath: `circle(${radius}px at 50% 50%)`
✓ What to DO
- ✓Changing the center (
at X% Y%) to reveal from a corner or from wherever the eye should go first. - ✓Use high damping (>18) for a smooth reveal without bounce.
- ✓Combine with vignette-pulse to keep the focus even after the reveal.
✗ What NOT to do
- ✗Use a radius smaller than the diagonal—it leaves dark corners visible.
- ✗Very high stiffness — a spring bounce on an image reveal looks like a glitch.
- ✗Use for very short transitions (<15 frames) — the effect won’t appear.
🌑 vignette-pulse vs. whip-pan — two opposite styles
O vignette-pulse is subtle and emotional: it darkens the edges of the screen in a pulse, drawing the eye to the center. The whip-pan is aggressive and dynamic: a fast horizontal shift with blur that simulates a camera pan at maximum speed.
vignette-pulse — subtle, focus
- •Black radial gradient at the edges with pulsing opacity via a sine wave.
- •Opacity:
0.3 + sin(frame * 0.1) * 0.15— a gentle, slow pulse. - •Ideal for documentaries, interviews, and narrative focus.
whip-pan — energetic, cut
- •Fast TranslateX with motion blur via
filter: blur()proportional to speed. - •Speed:
interpolate(frame, [0, dur/2, dur], [0, maxVel, 0]). - •Ideal for scene transitions, action videos, and fast-paced montages.
const velocity = interpolate( frame, [0, durationInFrames / 2, durationInFrames], [0, 400, 0], { extrapolateRight: "clamp" } ); const blurAmount = Math.abs(velocity) / 80; // style: { transform: `translateX(${velocity}px)`, filter: `blur(${blurAmount}px)` }
📚 Complete Library — all 9 templates
Quick reference for all cinematic templates, with file, core technique, and usage context.
📌 Module summary
sin(frame) × amplitude with decay via interpolate. Non-integer multipliers create an organic trajectory.clip-path: circle() with the radius growing from zero to the full diagonal.Conclusion of Track 2:
You’ve mastered the three categories of Remotion visual assets: images & media, backgrounds, and cinematic effects. Track 3 — Combining — shows you how to chain these templates into complete narrative sequences.