Motion One is a relatively fresh animation library that runs on the Web Animations API. If you have worked with Popmotion or Greensock in the past, you will likely recognize the overall syntax immediately.

The goal of this post is to demonstrate how Motion One can be integrated into an Angular project. I will cover the setup steps, build a straightforward animation, and then look at the spring and timeline utilities that Motion One ships with.

You can find a live, interactive demo as part of my Angular Animation Explorer.

Installation

The first step is to install the library through npm with the command below.

npm install --save motion
Enter fullscreen mode Exit fullscreen mode

If TypeScript complains about typings, you can try adding skipLibCheck: true to your tsconfig.json.

A First Animation

motion one default animation

To target an element in your template, you must assign it an id so it can be referenced from your TypeScript file.

<div #myElement>...</div>
Enter fullscreen mode Exit fullscreen mode

Once the id is in place, the element can be pulled into your component class with Angular's ViewChild decorator.

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  ...
})
export class MotionOneDemoComponent {
  @ViewChild('myElement') myElement: ElementRef;

}
Enter fullscreen mode Exit fullscreen mode

With the element reference available, you are ready to invoke Motion One's animation APIs to bring it to life.

import { Component, ViewChild, ElementRef } from '@angular/core';
import { animate } from 'motion';

@Component({
  ...
})
export class MotionOneDemoComponent {
  @ViewChild('myElement') myElement: ElementRef;

  animateMyElement(): void {
    animate(
      this.myElement.nativeElement,
      { rotate: 180 },
      { duration: 0.5, easing: 'ease-in' }
    ).finished.then(() => {
        // animation completed
      })
      .catch(() => {
        // if an error happens
      });
  }
}
Enter fullscreen mode Exit fullscreen mode

Springs and Glides

motion one spring animation

Motion One includes preconfigured easings like spring and glide. These are used by passing their respective functions into the animation options, along with any extra configuration they accept. The following snippet illustrates how a basic spring animation is put together:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { animate, spring } from 'motion';

@Component({
  ...
})
export class MotionOneDemoComponent {
  @ViewChild('myElement') myElement: ElementRef;

  animateMyElement(): void {
    animate(
      this.myElement.nativeElement,
      { rotate: 180 },
      { duration: 0.5, easing: spring() } // 👈 modify the easing
    ).finished.then(() => {
        // animation completed
      })
      .catch(() => {
        // if an error happens
      });
  }
}
Enter fullscreen mode Exit fullscreen mode

Building Timelines

motion one timeline animation

Timelines are another notable feature in Motion One's toolbox. By constructing an array of animations and feeding it to the timeline function, you can orchestrate multiple animations on different elements simultaneously or in sequence.

The timeline API behaves much like Greensock's timeline. The example below demonstrates how a box can be translated through a chained sequence of keyframes.

import { Component, ViewChild, ElementRef } from '@angular/core';
import { timeline } from 'motion';

@Component({
  ...
})
export class MotionOneDemoComponent {
  @ViewChild('myElement') myElement: ElementRef;

  animateMyElement(): void {
    const sequence = [
      [this.myElement.nativeElement, { x: 100 }, { duration: 0.5 }],
      [this.myElement.nativeElement, { y: 100 }, { duration: 0.5 }],
      [this.myElement.nativeElement, { x: 0, y: 0 }, { duration: 1 }],
    ];
    timeline(sequence)
      .finished.then(() => {
        // animation completed
      })
      .catch(() => {
        // if an error happens
      });
  }
}
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Compared to many established animation libraries, Motion One is still maturing. Even so, it already offers a rich feature set, solid performance, and a straightforward developer experience. This guide only scratches the surface of what the library can do. More advanced topics are on the horizon, and I plan to write a follow-up post that explores them in greater detail.

For further questions or feedback, feel free to leave a comment or reach out on Twitter at @williamjuan27