# Using interpolate() in Remotion for Smooth Animations and Value Transformations

> Master smooth animations and value transformations in Remotion with interpolate(). Learn linear interpolation, easing, and extrapolation for powerful visual effects.

- Repository: [Remotion/remotion](https://github.com/remotion-dev/remotion)
- Tags: how-to-guide
- Published: 2026-02-15

---

**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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/interpolate.ts)**: Core numeric interpolation logic, validation, and extrapolation handling.
- **[`packages/core/src/interpolate-colors.ts`](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/interpolate-colors.ts)**: Color string normalization and per-channel interpolation via `interpolateColors()`.
- **[`packages/core/src/easing.ts`](https://github.com/remotion-dev/remotion/blob/main/packages/core/src/easing.ts)**: Built-in easing function definitions including sine, cubic, and bezier curves.
- **[`packages/core/src/test/interpolate.test.ts`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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`](https://github.com/remotion-dev/remotion/blob/main/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.