# How to Use Custom Easing Functions in Anime.js: A Complete Guide to Cubic Bézier, Spring Physics, and More

> Master custom easing functions in Anime.js. Explore cubic Bézier, spring physics, and more for dynamic animations. Learn to create unique motion with this comprehensive guide.

- Repository: [Julian Garnier/anime](https://github.com/juliangarnier/anime)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Anime.js supports custom easing functions through cubic Bézier curves, step-wise jumps, piecewise linear interpolation, parameterized Penner formulas, spring physics, and raw mathematical functions, all exported from the main module and processed by the `parseEase` parser in [`src/easings/eases/parser.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/eases/parser.js).**

Anime.js provides a powerful animation engine that extends far beyond standard easing presets. When you need precise control over acceleration curves for specific motion design requirements, the library offers multiple factory methods to define custom easing functions. This guide examines the implementation details and usage patterns for each approach based on the Anime.js source code.

## How the Easing Parser Works

Before an easing function reaches the animation loop, Anime.js processes it through `parseEase` in [`src/easings/eases/parser.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/eases/parser.js). This parser normalizes any easing input into a standard function signature `(t: number) => number`:

1. **Function detection**: If the value is already a function, it passes through unchanged.
2. **String parsing**: Named easings like `"outQuad"` are looked up in the cached `easesLookups` registry.
3. **Factory invocation**: Strings containing parentheses (e.g., `"cubicBezier(0.4,0,0.2,1)"`) trigger the corresponding factory function with parsed arguments.
4. **Normalization**: The final output is always a normalized easing function receiving time `t ∈ [0,1]`.

The parser caches string-based lookups to avoid recomputing named easings on every animation frame.

## Creating Custom Easing Functions

Anime.js exports six primary factory methods from [`src/index.js`](https://github.com/juliangarnier/anime/blob/main/src/index.js) for constructing custom easings. Each generates a normalized easing function compatible with the `ease` property.

### Cubic Bézier Curves with cubicBezier()

The `cubicBezier(x1, y1, x2, y2)` factory in [`src/easings/cubic-bezier/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/cubic-bezier/index.js) generates CSS-compatible Bézier curves. The implementation solves the cubic equation to map input time `t` to output value `y` using the four control points.

```javascript
import { animate, cubicBezier } from 'animejs';

animate('.box', {
  translateX: 300,
  duration: 1200,
  // Material Design "fast-out-slow-in" curve
  ease: cubicBezier(0.4, 0, 0.2, 1),
});

```

### Step-wise Animation with steps()

For discrete, frame-like motion, the `steps(count, fromStart?)` factory in [`src/easings/steps/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/steps/index.js) creates a staircase function. The `fromStart` boolean (default `false`) determines whether jumps occur at the start or end of each interval.

```javascript
import { animate, steps } from 'animejs';

animate('.dot', {
  opacity: [0, 1],
  duration: 800,
  // 5 discrete jumps, starting at the beginning of each step
  ease: steps(5, true),
});

```

### Piecewise Linear Interpolation with linear()

The `linear(...points)` factory in [`src/easings/linear/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/linear/index.js) constructs easing functions from arbitrary control points. Accept numbers or percentage strings (`'25% 75%'`) to define non-uniform acceleration curves.

```javascript
import { animate, linear } from 'animejs';

animate('.bar', {
  width: ['0%', '100%'],
  duration: 1500,
  // Hold at 0.25 until 30% of time, then jump to 0.75 at 70%
  ease: linear(0, '0.25 30%', '0.75 70%', 1),
});

```

### Parameterized Penner Easings with eases()

The `eases` object in [`src/easings/eases/parser.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/eases/parser.js) (lines 44-48) exposes factories for Penner equations with custom parameters. Use `eases.in(p)`, `eases.out(p)`, `eases.inOut(p)`, and `eases.outIn(p)` for power-based curves, or specialized methods for Back and Elastic effects.

```javascript
import { animate, eases } from 'animejs';

// Custom cubic-in curve (power = 3)
animate('.ball', {
  scale: [0, 1],
  duration: 600,
  ease: eases.in(3),
});

// Elastic easing with custom amplitude and period
animate('.spring', {
  translateY: [0, -200],
  duration: 1200,
  ease: eases.outElastic(1.5, 0.5),
});

```

The parser implements these at lines 33 (power functions) and 78-86 (Elastic definitions).

### Spring Physics with spring()

For physically-based motion, the `spring(options)` factory in [`src/easings/spring/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/spring/index.js) (lines 49-94) creates easings derived from mass-spring-damper systems. The solver automatically calculates duration based on physical parameters rather than using a fixed duration.

```javascript
import { animate, spring } from 'animejs';

animate('.panel', {
  rotate: [0, 360],
  // Heavy mass with low stiffness creates a long, overshooting motion
  ease: spring({ mass: 5, stiffness: 30, damping: 12 }),
});

```

### Raw Mathematical Functions

Any function conforming to `(t: number) => number` can be passed directly to the `ease` property. Anime.js uses this function verbatim without parsing, bypassing the `parseEase` logic entirely.

```javascript
import { animate } from 'animejs';

animate('.dot', {
  opacity: [0, 1],
  duration: 500,
  // Simple quadratic ease-in
  ease: t => t * t,
});

```

## Summary

- **Cubic Bézier curves** generated by `cubicBezier()` in [`src/easings/cubic-bezier/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/cubic-bezier/index.js) provide CSS-compatible timing functions using four control points.
- **Step-wise easings** created with `steps()` in [`src/easings/steps/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/steps/index.js) produce discrete frame-like motion with configurable jump points.
- **Piecewise linear interpolation** via `linear()` in [`src/easings/linear/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/linear/index.js) allows arbitrary control point definitions using numbers or percentage strings.
- **Parameterized Penner equations** exposed through the `eases` object in [`src/easings/eases/parser.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/eases/parser.js) support custom power curves, Back overshoot, and Elastic amplitude/period adjustments.
- **Spring physics** simulated by `spring()` in [`src/easings/spring/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/spring/index.js) generate physically-based motion using mass, stiffness, and damping parameters with automatically calculated duration.
- **Raw functions** bypass the parser entirely, accepting any `(t) => number` implementation directly.
- All factories are exported from [`src/index.js`](https://github.com/juliangarnier/anime/blob/main/src/index.js) and normalized through `parseEase` in [`src/easings/eases/parser.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/eases/parser.js).

## Frequently Asked Questions

### How do I import custom easing factories in Anime.js?

All custom easing factories—including `cubicBezier`, `steps`, `linear`, `spring`, and the `eases` object—are exported from the main entry point. Import them directly alongside the `animate` function using `import { animate, cubicBezier, spring } from 'animejs';`.

### Can I use CSS cubic-bezier values directly in Anime.js?

Yes. The `cubicBezier(x1, y1, x2, y2)` factory in [`src/easings/cubic-bezier/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/cubic-bezier/index.js) accepts the same four numeric values used in CSS `cubic-bezier()` timing functions. The implementation solves the cubic Bézier equation mathematically to ensure identical acceleration curves across browsers.

### What is the difference between steps() and linear() easing?

The `steps(count, fromStart)` function in [`src/easings/steps/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/steps/index.js) creates a staircase effect that jumps between discrete values without interpolation, similar to CSS `steps()`. In contrast, `linear(...points)` in [`src/easings/linear/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/linear/index.js) interpolates linearly between specified control points, creating continuous straight-line segments rather than jumps.

### How does the spring() function calculate animation duration?

Unlike other easings that map time to progress within a fixed duration, the `spring(options)` factory in [`src/easings/spring/index.js`](https://github.com/juliangarnier/anime/blob/main/src/easings/spring/index.js) (lines 49-94) derives duration automatically from physical parameters. The `Spring` class simulates a mass-spring-damper system and computes when the motion settles below a rest threshold, returning an easing function with an implicit duration calculated from the physics simulation rather than a predefined millisecond value.