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:

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.ts within the remotion-dev/remotion repository.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →