# motion-frame

> A Typescript lambda animation / easing engine

Latest version **2.1.0** (published 2025-07-02) · MIT license · 0 weekly downloads

## Install

```sh
npm install motion-frame
pnpm add motion-frame
yarn add motion-frame
bun add motion-frame
```

## Health

**Score 35/100 (D)** — status: maintenance-mode.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2025-07-02 |
| First published | 2022-11-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 35.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Simon Watson |
| Maintainers | mrsimmons |
| Keywords | animation, requestAnimationFrame, typescript, javascript, lambda, lerp |

## Links

- npm: https://www.npmjs.com/package/motion-frame
- Repository: https://github.com/MrSimmmons/motion-frame
- Homepage: https://github.com/MrSimmmons/motion-frame#readme
- Issues: https://github.com/MrSimmmons/motion-frame/issues
- npm.io page: https://npm.io/package/motion-frame

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 2.1.0 (latest) — 2025-07-02
- 2.0.2 — 2022-12-04
- 2.0.1 — 2022-11-11
- 2.0.0 — 2022-11-11
- 1.0.0 — 2022-11-11

## README

# Motion Frame

A Typescript lambda animation / easing engine built on top of requestAnimationFrame

## About

Motion Frame is an animation engine that is run off the concept of lambda animation functions. The way that these functions work is that you define the end state of an animation that you want in JS, and then multiply any values with the provided easing variable `x` (value between 0 and 1) and then let the engine work its magic :)

### Usage

To use Motion Frame, run `npm install motion-frame` and import `Motion` and / or `MotionChain` into your project. `Motion` is the main class to use to initiated your animations, while `MotionChain` allows you to chain animations together to then play in order. To use them, you need to provide an `MotionProps` object in the constructor (in the the `MotionChain`'s case, an array of `MotionProps`)

| Key                    | Type                           | Default         | Description                                                                       |
| --------------         | ------------------------------ | --------------- | --------------------------------------------------------------------------------- |
| `animation` (required) | Function (AnimationFrame)      | `void`          | The lambda animation that will run                                                |
| `easing`               | Function (x)                   | `(x) => x`      | The easing function that the animation will take                                  |
| `duration`             | Number                         | `1000`          | The duration of the animation in milliseconds                                     |
| `reverse`              | Boolean                        | `false`         | If the animation should play in reverse                                           |
| `loop`                 | LoopType                       | `LoopType.NONE` | If the animation should loop after it finishes                                    |
| `before`               | Function (state)               | `(state) => {}` | A function that will trigger before the animation has begun (resets after `stop`) |
| `after`                | Function (state)               | `(state) => {}` | A function that will trigger once the animation has finished each run             |
| `state`                | Object                         | `{}`            | Persistent state that can be accessed within the `animation` and `after` lambdas  |
| `reset`                | Function                       | `void`          | Gets called immediately after the animation gets reset to its original position   |

### Example

```ts
import { Motion } from "motion-frame";

const boxElement = document.getElementById("box");
const boxRect = boxElement.getBoundingClientRect();

const boxAnimation = new Motion({
  duration: 2000,
  loop: LoopType.ALTERNATE,
  easing: (x) => x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2, // easeInOutQuart
  animation: (frame) => {
    let destX = (window.innerWidth - boxRect.width) / 2;
    let amountX = (destX - boxRect.left) * frame.progress;

    boxElement.style.left = `${amountX}px`;
  },
  after: () => {
    boxElement.innerHTML = boxAnimation.playCount;
  }
});

boxAnimation.play();
```

![Box animation](docs/example.gif)

### AnimationFrame

The animation function receives an object containing three parameters:

- `progress` (number): The eased progress value (0-1) after the easing function has been applied
- `progressMs` (number): (number): The unmodified progress value (0-1) before easing is applied
- `state` (TState): The persistent state object

This allows you to use different progression values for different aspects of your animation:

```ts
import { Motion } from "motion-frame";

const complexAnimation = new Motion({
  duration: 1000,
  easing: (x) => x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2, // easeInOutQuart
  animation: (frame) => {
    const { progress, progressMs } = frame;

    // Use eased value for position (accelerated movement)
    element.style.left = `${progress * 100}px`;
   
    // Use linear value for opacity (steady fade)
    element.style.opacity = progressMs;
  }
});
```

#### TODO - Future enhancements / additions

1. Make some pre-build easing functions available
1. Create a bunch of examples for all the different features
1. Build out extra documentation and examples around `MotionChain`
1. Unit tests

---
_Source: https://npm.io/package/motion-frame · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
