My first try of the new Web Animation API
Tags: javascript, animation, css, webanimationapi
Published: 2018-12-28 10:00:37

---
title: My first try of the new Web Animation API
published: true
description: Recently, I (finally) found out the new Animation API, which can use JavaScript to create smooth animation just like CSS one, but with more features, like changing speed or play/pause/cancel animations. Developer can have more flexibilities to create different animations.
tags: javascript, animation, css, Web Animation API
cover_image: https://thepracticaldev.s3.amazonaws.com/i/0znjuy2k3cltjm6aci3k.jpeg
---

Recently, I (finally) found out the new Web Animation API, which can use JavaScript to create smooth animation just like CSS one, but with more features, like changing speed or play/pause/cancel animations. Developer can have more flexibilities to create different animations.

> Note: The web animation API is still an experimental technology, not all browsers supported it. Don't forget to add [polyfill](https://github.com/web-animations/web-animations-js) before use!

---

## First Try

This time, I am trying to create animations of gears, since it is normal to see gears in different speeds or users can choose to start/stop animation when in need.

Normally, you can use CSS to create rotating gears like:

```css
.gear1 {
    animation: gears 1500ms infinite;
}

@keyframes gears {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
```

But now, you can use few lines of Javascript to create the same effects:

```javascript
  const rotate = [
    { transform: "rotate(0deg)" },
    { transform: "rotate(360deg)" }
  ];

  const timing = {
    duration: 1500,
    iterations: Infinity
  };

  const firstGear = document.getElementById("gear1").animate(rotate, timing);
```

You can see that the settings on `@keyframes` is moved to the first part of animate(), and one different thing from CSS is `infinite` changes to `iterations: Infinity` in the new Web Animation API (WAAPI).

First animation using WAAPI:

{% codepen https://codepen.io/snowleo208/pen/QzqbZW default-tab=js,result %}

You can also control percentage in animation just like CSS: 

```javascript
const blink = [
  { transform: "rotate(0deg)", opacity: 1, offset: 0 },
  { opacity: 0, offset: 0.3 },
  { opacity: 1, offset: 0.5 },
  { opacity: 0, offset: 0.7 },
  { opacity: 1, offset: 0.9 },
  { transform: "rotate(360deg)", opacity: 1, offset: 1 }
];

  const timing = {
    duration: 1500,
    iterations: Infinity
  };

const firstGear = document.getElementById("gear1").animate(blink, timing);
```

As you can see, the `offset: 0` is just like `0%` in CSS's keyframes, you can change different properties like color, transform, opacity etc. as you like.

For the timing, you can also add other settings like delay, easing, fill etc. You can view the full list [here](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate).

---

## Control Animation

After creating gears, you can also control the animation using Javascript. Like what we do at the first part, we declared the gear element as `firstGear`, now we can use it to switch on or off the animation.

For example, you can create a button, when user clicks that, it will stop the animation.

```html
<button id="stop">Stop</button>
```

Then, just add one line of javascript, you are done: 

```javascript

document.getElementById("stop").addEventListener("click", function() {
    firstGear.pause();
});

```

You can also use these to start or cancel the animation:

```javascript
firstGear.start();
firstGear.pause();
firstGear.cancel();
firstGear.reverse();
```

For reverse, only normal animation can use reverse. If you are creating infinite animation like this gear, you cannot simply use `<YOUR-ELEMENT>.reverse()`. 

In this case, we can use `direction` in the timing variable:

```javascript
const timing = {
    duration: 1500,
    direction: "reverse",
    iterations: Infinity
  };
```

{% codepen https://codepen.io/snowleo208/pen/ebGNjd default-tab=js,result %}

---

## Speed is king!

How can we change the animation speed after some events (e.g. after clicking button)?

```javascript

document.getElementById('<YOUR-ELEMENT>').addEventListener("click", function() {
    firstGear.playbackRate = 2; //speed x 2
    firstGear.playbackRate = 1; //normal speed
    firstGear.playbackRate = -1; //reverse your animation!
});

```

If you like, you can even set some conditions inside! For example, the loading animation, the gears can move slow at first, but when the page is nearly loaded, the gear speed can be faster!

View my complete gears here: 
{% codepen https://codepen.io/snowleo208/pen/jXLowg default-tab=js,result %}

---

## And more?

Unfortunately, the support of WAAPI [is not very good](https://caniuse.com/#feat=web-animation) right now, some features are not supported in current browsers. 

For example, if you need to change animation, like switch from rotating effects to fading effects. You will need to use `composite` and `iterationComposite` property, with the setKeyframes() function. Sadly, all are not fully supported in modern browsers.

Nevertheless, we are still able to create smooth animations with more controls using basic functions. Hope browsers can support more and more features in the future!


---

## Read More

- [Using the Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API)
- [CSS Animations vs Web Animations API](https://css-tricks.com/css-animations-vs-web-animations-api/)
- [Additive Animation with the Web Animations API](https://css-tricks.com/additive-animation-web-animations-api/)