Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply best practices for creating programmatic videos with Remotion and React.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/timing.md
1---2name: timing3description: Interpolation curves in Remotion - linear, easing, spring animations4metadata:5tags: spring, bounce, easing, interpolation6---78A simple linear interpolation is done using the `interpolate` function.910```ts title="Going from 0 to 1 over 100 frames"11import { interpolate } from "remotion";1213const opacity = interpolate(frame, [0, 100], [0, 1]);14```1516By default, the values are not clamped, so the value can go outside the range [0, 1].17Here is how they can be clamped:1819```ts title="Going from 0 to 1 over 100 frames with extrapolation"20const opacity = interpolate(frame, [0, 100], [0, 1], {21extrapolateRight: "clamp",22extrapolateLeft: "clamp",23});24```2526## Spring animations2728Spring animations have a more natural motion.29They go from 0 to 1 over time.3031```ts title="Spring animation from 0 to 1 over 100 frames"32import { spring, useCurrentFrame, useVideoConfig } from "remotion";3334const frame = useCurrentFrame();35const { fps } = useVideoConfig();3637const scale = spring({38frame,39fps,40});41```4243### Physical properties4445The default configuration is: `mass: 1, damping: 10, stiffness: 100`.46This leads to the animation having a bit of bounce before it settles.4748The config can be overwritten like this:4950```ts51const scale = spring({52frame,53fps,54config: { damping: 200 },55});56```5758The recommended configuration for a natural motion without a bounce is: `{ damping: 200 }`.5960Here are some common configurations:6162```tsx63const smooth = { damping: 200 }; // Smooth, no bounce (subtle reveals)64const snappy = { damping: 20, stiffness: 200 }; // Snappy, minimal bounce (UI elements)65const bouncy = { damping: 8 }; // Bouncy entrance (playful animations)66const heavy = { damping: 15, stiffness: 80, mass: 2 }; // Heavy, slow, small bounce67```6869### Delay7071The animation starts immediately by default.72Use the `delay` parameter to delay the animation by a number of frames.7374```tsx75const entrance = spring({76frame: frame - ENTRANCE_DELAY,77fps,78delay: 20,79});80```8182### Duration8384A `spring()` has a natural duration based on the physical properties.85To stretch the animation to a specific duration, use the `durationInFrames` parameter.8687```tsx88const spring = spring({89frame,90fps,91durationInFrames: 40,92});93```9495### Combining spring() with interpolate()9697Map spring output (0-1) to custom ranges:9899```tsx100const springProgress = spring({101frame,102fps,103});104105// Map to rotation106const rotation = interpolate(springProgress, [0, 1], [0, 360]);107108<div style={{ rotate: rotation + "deg" }} />;109```110111### Adding springs112113Springs return just numbers, so math can be performed:114115```tsx116const frame = useCurrentFrame();117const { fps, durationInFrames } = useVideoConfig();118119const inAnimation = spring({120frame,121fps,122});123const outAnimation = spring({124frame,125fps,126durationInFrames: 1 * fps,127delay: durationInFrames - 1 * fps,128});129130const scale = inAnimation - outAnimation;131```132133## Easing134135Easing can be added to the `interpolate` function:136137```ts138import { interpolate, Easing } from "remotion";139140const value1 = interpolate(frame, [0, 100], [0, 1], {141easing: Easing.inOut(Easing.quad),142extrapolateLeft: "clamp",143extrapolateRight: "clamp",144});145```146147The default easing is `Easing.linear`.148There are various other convexities:149150- `Easing.in` for starting slow and accelerating151- `Easing.out` for starting fast and slowing down152- `Easing.inOut`153154and curves (sorted from most linear to most curved):155156- `Easing.quad`157- `Easing.sin`158- `Easing.exp`159- `Easing.circle`160161Convexities and curves need be combined for an easing function:162163```ts164const value1 = interpolate(frame, [0, 100], [0, 1], {165easing: Easing.inOut(Easing.quad),166extrapolateLeft: "clamp",167extrapolateRight: "clamp",168});169```170171Cubic bezier curves are also supported:172173```ts174const value1 = interpolate(frame, [0, 100], [0, 1], {175easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),176extrapolateLeft: "clamp",177extrapolateRight: "clamp",178});179```180