@okikio/animate - the animation library built using the Web Animation API (WAAPI)
Tags: webdev, typescript, javascript, webanimation
Published: 2021-05-26 01:17:57

---
title: @okikio/animate - the animation library built using the Web Animation API (WAAPI)
description: @okikio/animate is an animation library for the modern web, it uses the Web Animation API to deliver butter smooth animations at a small size.
canonical_url: https://css-tricks.com/how-i-used-the-waapi-to-build-an-animation-library/
tags: webdev, typescript, javascript, webanimation
published: true
---

<!-- # Using the Web Animation API in 2021, introducing @okikio/animate - the animejs-esque animation library built on the Web Animation API

![An image of a CSS Keyframe statement that defines the animation for a ripple, by Pankaj Patel on Unsplash.](https://paper-attachments.dropbox.com/s_3C2FDE320243B07D013B560D8A0D8A53D0F92F80385468255076AD9FCCFAA2C8_1622175656362_pankaj-patel-SXihyA4oEJs-unsplash.jpg) -->

### Table of Contents

- [Introduction](#introduction)
- [This is the library I made with the WAAPI](#this-is-the-library-i-made-with-the-waapi)
  - [The story behind `@okikio/animate`](#the-story-behind-okikioanimate)
  - [Where `@okikio/animate` fits into this article](#where-okikioanimate-fits-into-this-article)
- [Now, let’s get started](#now-lets-get-started)
- [Usage, examples and demos](#usage-examples-and-demos)
- [Restrictions and limitations](#restrictions-and-limitations)
- [Looking to the future](#looking-to-the-future)
- [Polyfills](#polyfills)
- [Conclusion](#conclusion)
  
**TLDR** `@okikio/animate` is basically `animejs` but built on the Web Animation API.

### Introduction

The Web Animations API lets us construct animations and control their playback with JavaScript. The API opens the browser’s animation engine to developers and was designed to underlie implementations of both CSS animations and transitions, leaving the door open to future animation effects. It is one of the most performant ways to animate on the Web, letting the browser make its own internal optimizations without hacks, coercion, or `window.requestAnimationFrame()`.

With the Web Animations API, we can move interactive animations from stylesheets to JavaScript, separating presentation from behavior. We no longer need to rely on DOM-heavy techniques such as writing CSS properties and scoping classes onto elements to control playback direction. And unlike pure, declarative CSS, JavaScript also lets us dynamically set values from properties to durations. For building custom animation libraries and creating interactive animations, the Web Animations API might be the perfect tool for the job. Let’s see what it can do!

For the rest of this article, I will sometimes refer to the Web Animation API as WAAPI. When searching for resources on the Web Animation API, you might be led astray by searching “Web Animation API” so, to make it easy to find resources, I feel we should adopt the term WAAPI; tell me what you think in the comments below.

### This is the library I made with the WAAPI

[@okikio/animate](https://www.npmjs.com/package/@okikio/animate) is an animation library for the modern web. It was inspired by [animateplus](https://github.com/bendc/animateplus), and [animejs](https://animejs.com/); it is focused on performance and developer experience, and utilizes the Web Animation API to deliver butter-smooth animations at a small size, weighing in at **~5.79 KB** (minified and gzipped).

#### The story behind `@okikio/animate`

In 2020, I decided to make a more efficient PJAX library, similar to [Rezo Zero’s](https://www.rezo-zero.com/) - [Starting Blocks](https://github.com/rezozero/starting-blocks) project, but with the ease of use of [barbajs](https://barba.js.org/). I felt starting blocks was easier to extend with custom functionality, and could be made smoother, faster, and easier to use.

**Note:** if you don’t know what a PJAX library is I suggest checking out [MoOx/pjax](https://github.com/MoOx/pjax); in short, PJAX allows for smooth transitions between pages using fetch requests and switching out DOM Elements.

Over time my intent shifted, and I started noticing how often sites from [awwwards.com](https://www.awwwards.com/) used PJAX, but often butchered the natural experience of the site and browser . Many of the sites looked cool at first glance, but the actual usage often told a different story — scrollbars were often overridden, prefetching was often too eager, and a lack of preparation for people without powerful internet connections, CPUs and/or GPUs. So, I decided to [progressively enhance](https://en.wikipedia.org/wiki/Progressive_enhancement) the library I was going to build. I started what I call the “native initiative” stored in the GitHub repo [okikio/native](https://github.com/okikio/native); a means of introducing all the cool and modern features in a highly performant, compliant, and lightweight way.

{% github okikio/native %}

For the native initiative I designed the PJAX library [@okikio/native](https://www.npmjs.com/package/@okikio/native); while testing on an actual project, I ran into the Web Animation API, and realized there were no libraries that took advantage of it, so, I developed [@okikio/animate](https://www.npmjs.com/package/@okikio/animate), to create a browser compliant animation library. (**Note**: this was in 2020, around the same time [use-web-animations](https://www.npmjs.com/package/@wellyshen/use-web-animations) by wellyshen was being developed. If you are using react and need some quick animate.css like effects, [use-web-animations](https://www.npmjs.com/package/@wellyshen/use-web-animations) is a good fit.) At first, it was supposed to be simple wrapper but, little by little, I built on it and it’s now at **80%** feature parity with more mature animation libraries.

**Note:** you can read more on the native initiative as well as the `@okikio/native` library on the [Github repo okikio/native](https://github.com/okikio/native). Also, okikio/native, is a [monorepo](https://lerna.js.org/) with `@okikio/native` and `@okikio/animate` being sub-packages within it.

#### Where `@okikio/animate` fits into this article

The Web Animation API is very open in design. It is functional on its own but it’s not the most developer-friendly or intuitive API, so I developed `@okikio/animate` to act as a wrapper around the WAAPI and introduce the features you know and love from other more mature animation libraries (with some new features included) to the high-performance nature of the Web Animation API. [Give the project’s README a read](https://github.com/okikio/native/tree/master/packages/animate#readme) for much more context.

### Now, let’s get started

@okikio/animate creates animations by creating new instances of Animate (a class that acts as a wrapper around the Web Animation API).

```ts
import { Animate } from"@okikio/animate";

new Animate({
    target: [/* ... */],
    duration: 2000,
    // ... 
});
```

The `Animate` class receives a set of targets to animate, it then creates a list of [WAAPI Animation instances](https://developer.mozilla.org/en-US/docs/Web/API/Animation), alongside a [main animation](https://github.com/okikio/native/tree/master/packages/animate#mainanimation-animation) (the main animation is a small Animation instance that is set to animate over a non-visible element, it exists as a way of tracking the progress of the animations of the various target elements), the `Animate` class then plays each target elements Animation instance, including the main animation, to create smooth animations.

The main animation is there to ensure accuracy in different browser vendor implementations of WAAPI. The main animation is stored in [Animate.prototype.mainAnimation](https://github.com/okikio/native/tree/master/packages/animate#mainanimation-animation), while the target element’s Animation instances are stored in a `WeakMap`, with the key being its [KeyframeEffect](https://developer.mozilla.org/en-US/docs/Web/API/KeyframeEffect). You can access the animation for a specific target using the [Animate.prototype.getAnimation(el)](https://github.com/okikio/native/tree/master/packages/animate#the-long-list-of-get-methods).

You don‘t need to fully understand the prior sentences, but they will aid your understanding of what `@okikio/animate` does. If you want to learn more about how WAAPI works, check out [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Animation), or if you would like to learn more about the `@okikio/animate` library, I’d suggest checking out the [okikio/native](https://github.com/okikio/native/tree/master/packages/animate#readme) project on GitHub.

### Usage, examples and demos

By default, creating a new instance of Animate is very annoying, so, I created the `animate` function, which creates new Animate instances every time it’s called.

```ts
import animate from "@okikio/animate";
// or
import { animate } from "@okikio/animate";

animate({ 
    target: [/* ... */],
    duration: 2000,
    // ... 
});
```

When using the `@okikio/animate` library to create animations you can do this:

```ts
import animate from "@okikio/animate";

// Do this if you installed it via the script tag: const { animate } = window.animate;

(async () => {
    let [options] = await animate({
    target: ".div",

    // Units are added automatically for transform CSS properties
    translateX: [0, 300],
    duration: 2000, // In milliseconds
    speed: 2,
    });

    console.log("The Animation is done...");
})();
```

{% codesandbox okikioanimate-getting-started-8mkp6 %}

You can also play with a demo with playback controls:

{% codepen https://codepen.io/okikio/pen/QWpjGaY default-tab=result %}

Try out Motion Path:

{% codepen https://codepen.io/okikio/pen/mdWEMjg default-tab=result %}

Try different types of Motion by changing the Animation Options:

{% codepen https://codepen.io/okikio/pen/JjWYRWz default-tab=result %}

I also created a complex demo page with polyfills:

[View demo](https://okikio.github.io/native/demo/animate.html)

You can find the source code for this demo in the [animate.ts](https://github.com/okikio/native/blob/master/build/ts/modules/animate.ts) and [animate.pug](https://github.com/okikio/native/blob/master/build/pug/animate.pug) files in the GitHub repo. And, yes, the demo uses Pug, and is a fairly complex setup. I highly suggest [looking at the README as a primer for getting started](https://github.com/okikio/native/tree/master/packages/animate#demo).

The native initiative uses [Gitpod](https://www.gitpod.io/), so if you want to play with the demo, I recommend clicking the [“Open in Gitpod”](https://github.com/okikio/native/tree/master/packages/animate#okikioanimate) link since the entire environment is already set up for you — there’s nothing to configure.

You can also check out some [more examples in this CodePen collection](https://codepen.io/collection/rxOEBO) I put together. For the most part, you can port your code from animejs to `@okikio/animate` with few-to-no issues.

I should probably mention that `@okikio/animate` supports both the `target` and `targets` keywords for settings animation targets. `@okikio/animate` will merge both list of targets into one list and use [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)s to remove any repeated targets. `@okikio/animate` supports functions as animation options, so you can use staggering similar to [animejs](https://animejs.com/documentation/#functionBasedParameters). (**Note**: the order of arguments are different, read more in the [“Animation Options & CSS Properties as Methods” section](https://github.com/okikio/native/tree/master/packages/animate#animation-options--css-properties-as-methods) of the README file.)

### Restrictions and limitations

@okikio/animate isn’t perfect; nothing really is, and seeing as the Web Animation API is a living standard constantly being improved, `@okikio/animate` itself still has lots of space to grow. That said, I am constantly trying to improve it and would love your input so please open a new issue, create a pull request or we can have a discussion [over at the GitHub project](https://github.com/okikio/native/tree/master/packages/animate#readme).

The first limitation is that it doesn’t really have a built-in timeline. There are a few reasons for this:

1.  I ran out of time. I am still only a student and don’t have lots of time to develop all the projects I want to.
2.  I didn’t think a formal timeline was needed, as async/await programming was supported. Also, I added [timelineOffset](https://github.com/okikio/native/tree/master/packages/animate#timelineoffset) as an animation option, should anyone ever need to create something similar to the timeline in animejs.
3.  I wanted to make `@okikio/animate` as small as possible.
4.  With [group effects](https://drafts.csswg.org/web-animations-2/#group-effect) and [sequence effects](https://drafts.csswg.org/web-animations-2/#sequence-effects) coming soon, I thought it would be best to leave the package small until an actual need comes up. On that note, I highly suggest reading [Daniel C. Wilson’s series on the WAAPI](https://danielcwilson.com/tags/web-animations-api/), particularly [the fourth installment](https://danielcwilson.com/blog/2015/09/animations-part-4/) that covers group effects and sequence effects.

Another limitation of `@okikio/animate` is that it lacks support for custom easings, like spring, elastic, etc. But check out [Jake Archibald’s proposal for an easing worklet](https://github.com/jakearchibald/easing-worklet). He discusses multiple standards that are currently in discussion. I prefer his proposal, as it’s the easiest to implement, not to mention the most elegant of the bunch. In the meanwhile, I'm taking inspiration from [Kirill Vasiltsov](https://www.kirillvasiltsov.com/) article on [Spring animations with WAAPI](https://www.kirillvasiltsov.com/writing/how-to-create-a-spring-animation-with-web-animation-api/) and I am planning to build something similar into the library.

~~The last limitation is that `@okikio/animate` only supports automatic units on transform functions e.g. `translateX`, `translate`, `scale`, `skew`, etc.~~ This is no longer the case as of `@okikio/animate@2.2.0`, but there are still some limitations on CSS properties that support color. Check the [GitHub release](https://github.com/okikio/native/releases/tag/%40okikio%2Fanimate%402.2.0) for more detail.

For example:

```ts
animate({
    targets: [".div", document.querySelectorAll(".el")],

    // By default "px", will be applied
    translateX: 300,
    left: 500,
    margin: "56 70 8em 70%",

    // "deg" will be applied to rotate instead of px
    rotate: 120, 

    // No units will be auto applied
    color: "rgb(25, 25, 25)",
    "text-shadow": "25px 5px 15px rgb(25, 25, 25)"
});
```

### Looking to the future

Some future features, like [ScrollTimeline](https://drafts.csswg.org/scroll-animations-1/), are right around the corner. I don’t think anyone actually knows when it will release but since the ScrollTimeline in Chrome Canary 92, I think it’s safe to say the chances of a release in the near future look pretty good.

I built the [timeline](https://github.com/okikio/native/tree/master/packages/animate#timeline) animation option into `@okikio/animate` to future-proof it. Here’s an example:

{% codepen https://codepen.io/okikio/pen/zYZEWJo default-tab=result %}

Thanks to Bramus for [the demo inspiration](https://codepen.io/bramus/pen/GRjPggQ)! Also, you may need the Canary version of Chrome or need to turn on Experimental Web Platform features in Chrome Flags to view this demo. It seems to work just fine on Firefox, though, so… 🤣.

If you want to read more on the ScrollTimeline, Bramus wrote [an excellent article on it](https://www.bram.us/2021/02/23/the-future-of-css-scroll-linked-animations-part-1/). I would also suggest reading the Google Developers [article on Animation Worklets](https://developers.google.com/web/updates/2018/10/animation-worklet).

My hope is to make the library smaller. It's currently **~5.79 KB** which seems high, at least to me. Normally, I would use a [bundlephobia](https://bundlephobia.com/package/@okikio/animate) embed but that has trouble bundling the project, so if you want to verify the size, I suggest using [bundlejs.com](https://bundlejs.com) because it actually bundles the code locally on your browser. I specifically built it for checking the bundle size of `@okikio/animate`, but note it's not as accurate as bundlephobia.

### Polyfills

[One of the earlier demos](https://okikio.github.io/native/demo/animate.html) shows polyfills in action. You are going to need [web-animations-next.min.js](https://github.com/web-animations/web-animations-js) from web-animations-js to support timelines. Other modern features the `KeyframeEffect` constructor is required.

The polyfill uses JavaScript to test if the `KeyframeEffect` is supported and, if it isn’t, the polyfill loads and does its thing. Just avoid adding async/defer to the polyfill, or it will not work the way you expect. You’ll also want to polyfill `Map`, `Set`, and `Promise`.

```html
<html>
    <head>
        <!-- Async -->
        <script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=default,es2015,es2018,Array.prototype.includes,Map,Set,Promise" async></script>

        <!-- NO Async/Defer -->
        <script src="./js/webanimation-polyfill.min.js"></script>
    </head>
    <body>
        <!-- Content -->
    </body>
</html>
```

And if you’re building for ES6+, I highly recommend using [esbuild](https://esbuild.github.io/) for transpiling, bundling, and minifying. For ES5, I suggest using esbuild (with minify off), [Typescript](https://www.typescriptlang.org/) (with target of ES5), and [terser](http://terser.org/); as of now, this is the fastest setup to transpile to ES5, it's faster and more reliable than babel. See the [Gulpfile](https://github.com/okikio/native/blob/1ac1a166aed63c128ed9ca875fb8b817b9c9fb08/gulpfile.js#L143) from the demo for more details.

### Conclusion

@okikio/animate is a wrapper around the Web Animation API (WAAPI) that allows you to use all the features you love from animejs and other animation libraries, in a small and concise package. So, what are your thoughts after reading about it? Is it something you think you’ll reach for when you need to craft complex animations? Or, even more important, is there something that would hold you back from using it? Leave a comment below or join the discussion on [Github Discussions](https://github.com/okikio/native/discussions/5).

* * *

This article also [appeared on hackernoon](https://hackernoon.com/introducing-the-web-animations-api-and-okikioanimate-qx4e35mx), my blog [blog.okikio.dev](https://blog.okikio.dev/okikioanimate-the-animation-library-built-using-web-animations-api-waapi) and on [CSS-Tricks](https://css-tricks.com/how-i-used-the-waapi-to-build-an-animation-library/).  
Photo by [Pankaj Patel](https://unsplash.com/@pankajpatel) on [Unsplash](https://unsplash.com/).