Using interpolate() in Remotion for Smooth Animations and Value Transformations
The interpolate() function in Remotion maps numeric input values to output ranges using linear interpolation, with support for easing curves and four extrapolation strategies including clamp, wrap, and extend.
interpolate() serves as the foundational utility that drives value-based animations in the remotion-dev/remotion repository. This core function transforms numeric inputs across defined ranges, enabling smooth transitions for position, opacity, scale, and rotation values in React-based video compositions. Whether you are creating simple linear tweens or complex eased motions, understanding interpolate() is essential for mastering Remotion’s animation system.
How interpolate() Works Under the Hood
The implementation in packages/core/src/interpolate.ts processes animations through a rigorous pipeline that ensures mathematical accuracy and flexible output.
Parameter Validation
First, the function validates that input, inputRange, and outputRange are defined, share identical lengths, contain only finite numbers, and that inputRange is strictly monotonically increasing. This strict validation occurs in lines 27-53 of interpolate.ts to prevent ambiguous mappings.
Default Option Handling
When no easing function is provided, the identity function is applied. The extrapolateLeft and extrapolateRight options default to 'extend', allowing values to continue linearly beyond defined ranges unless explicitly constrained (lines 54-66).
Finding the Active Segment
The findRange() helper walks the inputRange array to locate the two surrounding points that bracket the current input value, identifying which segment requires interpolation (lines 76-84).
Segment Interpolation Logic
The selected segment is passed to interpolateFunction(), which applies the chosen extrapolation policy, maps the input to a normalized 0-1 range, executes the easing function, and scales the result into the output range (lines 18-73).
Understanding Extrapolation Modes
When input values fall outside the defined inputRange, four strategies control the output behavior:
- extend (default): Continues the linear trend beyond the supplied range boundaries.
- clamp: Restricts output to the nearest endpoint value, preventing overshoot.
- wrap: Cycles the value around the range, creating seamless loops for rotational or cyclic animations.
- identity: Returns the original input value unchanged when outside the defined range.
Working with Easing Functions
Easing functions transform normalized progress values (0 to 1) to create acceleration and deceleration curves. Remotion provides standard easing definitions in packages/core/src/easing.ts, including Easing.sin, Easing.cubic, and Easing.quadratic. You can also supply any custom function matching the signature (t: number) => number through the easing option.
Practical Code Examples
Basic Linear Tween
Map a progress value from 0-1 to a pixel position:
import {interpolate} from 'remotion';
const progress = 0.4;
const x = interpolate(progress, [0, 1], [0, 500]);
// Returns: 200
At 40% of the animation duration, the element is positioned at 200 pixels.
Applying Easing Curves
Add smooth acceleration using built-in easing functions:
import {interpolate, Easing} from 'remotion';
const t = 0.5;
const y = interpolate(t, [0, 1], [0, 100], {
easing: Easing.sin,
});
// Returns approximately 29.29
The sine easing creates slow start and end points with faster motion in the middle.
Clamping Values
Prevent values from exceeding boundaries:
const value = interpolate(-2, [0, 1, 2], [0, 10, 20], {
extrapolateLeft: 'clamp',
});
// Returns: 0
Even with an input of -2, the output remains clamped to the leftmost value of 0.
Creating Looping Animations
Use wrap mode for cyclic motion:
const rotation = interpolate(
frame % 30,
[0, 30],
[0, 360],
{extrapolateRight: 'wrap'}
);
// Returns 0-360 degrees that loops every 30 frames
When the frame exceeds 30, the value wraps to create continuous rotation.
Color Interpolation with interpolateColors()
For transitioning between CSS color values, use the specialized color interpolator:
import {interpolateColors} from 'remotion';
const bg = interpolateColors(
progress,
[0, 0.5, 1],
['#ff0000', '#00ff00', '#0000ff']
);
// Returns rgba() string transitioning red → green → blue
The interpolateColors() function in packages/core/src/interpolate-colors.ts processes each color string into ARGB integers using processColor() (lines 40-45), then interpolates each RGBA channel separately before returning a valid CSS color string.
Key Source Files
The interpolation system is implemented across these locations in the remotion-dev/remotion repository:
packages/core/src/interpolate.ts: Core numeric interpolation logic, validation, and extrapolation handling.packages/core/src/interpolate-colors.ts: Color string normalization and per-channel interpolation viainterpolateColors().packages/core/src/easing.ts: Built-in easing function definitions including sine, cubic, and bezier curves.packages/core/src/test/interpolate.test.ts: Comprehensive test suite covering edge cases, extrapolation modes, and error handling.
Summary
interpolate()maps numeric inputs to output ranges using linear interpolation with configurable easing and extrapolation strategies.- The function enforces strict validation in
packages/core/src/interpolate.ts, requiring monotonically increasing input ranges and finite numbers. - Four extrapolation modes (
extend,clamp,wrap,identity) control behavior outside defined ranges. - Easing functions accept normalized 0-1 values and can be custom functions or built-in options from
Easing. - Color interpolation uses
interpolateColors()to transition between CSS color strings by processing ARGB channels. - All core logic resides in
packages/core/src/interpolate.tswithin theremotion-dev/remotionrepository.
Frequently Asked Questions
What is the difference between interpolate() and interpolateColors() in Remotion?
interpolate() handles numeric values only, mapping numbers between input and output ranges. interpolateColors() is a specialized wrapper that first converts CSS color strings (hex, rgb, named colors) into numeric ARGB values using processColor() in interpolate-colors.ts, then calls the numeric interpolator for each RGBA channel separately, finally returning a valid CSS color string.
How do I prevent interpolate() from returning values outside my output range?
Use the extrapolateLeft and extrapolateRight options set to 'clamp'. This restricts the output to the nearest boundary value when the input falls outside the input range. By default, Remotion uses 'extend', which continues the linear trend beyond the defined boundaries as implemented in interpolateFunction().
Can I use custom easing functions with interpolate()?
Yes, the easing option accepts any function matching the signature (t: number) => number where both input and output are normalized between 0 and 1. Remotion provides standard easing curves in packages/core/src/easing.ts such as Easing.sin, Easing.cubic, and Easing.bezier, but you can also implement custom spring physics or bezier curves.
What happens if my input range is not strictly increasing?
Remotion throws a validation error during runtime. The interpolate() function in packages/core/src/interpolate.ts explicitly checks that the inputRange array is strictly monotonically increasing (each value must be greater than the previous) on lines 27-53. This validation ensures the interpolation mapping is mathematically unambiguous and prevents undefined behavior.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →