Skip to content

Motion JS

The Motion component animates its root element declaratively with the Motion library. Describe the animation with the initial, animate and transition options: the initial styles are applied on mount, then the animate keyframes play on demand — or automatically when autoplay is enabled with data-option-autoplay.

The component is a thin, headless playback surface exposing imperative methods that an Action can call from any interaction: play() and reverse() always drive the animation declared by the options, while animate() runs a one-off to arbitrary keyframes. All its events bubble, so an ancestor Action can catch and route them; use the .stop event modifier to contain them in nested setups.

The motion peer dependency is resolved with a lazy import() the first time an animation is built, so it stays out of your main bundle until needed. See providing the Motion dependency to inject a specific build such as motion/mini.

Motion is the playback primitive of @studiometa/ui-motion, which also ships MotionScrollTimeline to drive a group of Motion children with the scroll, MotionSequence to compose them into one staggered timeline, and MotionView to play DOM updates as view transitions.

Installation

Motion ships in the separate @studiometa/ui-motion package, with motion as a peer dependency:

bash
npm install @studiometa/ui-motion motion

Importing a module only defines the class: no component registers itself. Register the ones a page uses, or reach for the package's lazy manifest:

js
import { registerComponents } from '@studiometa/js-toolkit';
import { Motion } from '@studiometa/ui-motion';
import { Action } from '@studiometa/ui';

registerComponents(Motion, Action);

Usage

Option values are parsed as JSON, so object keys must be quoted. The animation below plays once on mount, which a preview finishes booting before you look at it — hence the replay button, which calls play() to restart it:

Driving the animation with Action

Autoplay is off by default, so the playback is yours to control from any interaction — see the examples for a complete demo:

html
<div
  data-component="Motion"
  data-option-animate='{ "x": 100 }'>

</div>

<button data-component="Action" data-on:click="Motion->target.play()">Play</button>
<button data-component="Action" data-on:click="Motion->target.reverse()">Reverse</button>