This content originally appeared on JavaScript January and was authored by Emily Freeman
Many thanks to Charlie Gerard for this post! Learn more about Charlie and her work on her website.
Web APIs are always evolving. Some are well implemented in all browsers such as Console or Canvas, while others are still being defined with their spec being regularly updated before being fully part of the web platform.
One of the web APIs currently still at an experimental stage is the Web Animations API or WAAPI. Even though the initial version of the spec was published in 2012 and the API was first implemented in Firefox and Chrome in 2014, I only recently heard about it.
It allows developers to manipulate CSS animations from JavaScript. Its syntax is similar to the classic CSS animations but has additional features to make the creation and manipulation of animations easier for developers.
Let's walk through what it can do with a simple example.
Animating with the Web Animations API
Below, we have a cube rotating and changing color.
Using CSS animations, the code would look like this:
.rotating-cube{ width: 40px; height: 40px; margin: 50%; background-color: pink; animation: rotateCube 1s infinite; } @keyframes rotateCube{ 0%{ transform: rotate(0deg); } 30%{ background-color: purple; } 100%{ transform: rotate(180deg); } }
Now, let's see how we would recreate the same animation using the Web Animations API.
We need to start by creating a Keyframe Object that will contain the same information as our CSS keyframes.
var cubeRotating = [ {transform: 'rotate(0deg)', backgroundColor: 'pink'}, {backgroundColor: 'purple', offset: 0.3}, {transform: 'rotate(180deg)', backgroundColor: 'pink'} ]
Two main differences here are:
- We need to add
backgroundColor
in the other steps of the animation as well for it to work. - We do not need to indicate the percentage of time at which each step needs to be executed.
The WAAPI will automatically divide the animation in equal parts based on the number of keys, so the 2nd step where the background color changes will usually be triggered 50% of the way through the whole animation.
However, we wanted to change our color 30% of the way through so, to do this, we add an offset
property of 0.3.
One important thing to note is that there should be at least 2 keyframes defined to use this, otherwise it will throw NotSupportedError
.
Then, we also create an object to represent our timing properties.
var cubeTiming = { duration: 1000, iterations: Infinity }
There's a few differences between the expressions you would use in normal CSS animations and the ones you'd need to use with the Web Animations API.
The duration of the animation is expressed in milliseconds, so our 1s animation becomes 1000.
Also, we do not use "infinite" to express the animation iteration count but the JavaScript keyword Infinity
.
Finally, to trigger this animation, we use the Element.animate
method.
document.getElementById('cube').animate( cubeRotating, cubeTiming )
With this code, we get our cube rotating and changing color!
There's a few other ways to write this, so if you want to have a look, you can check this codepen.
That's not all though! The most powerful thing about the WAAPI is the ability to control the playback!
Controlling the animation playback
Calling the animate
method on an element starts the animation immediately but it's not always what we want, so we can call pause
and play
to control when we'd want to stop and start the animation.
var cubeAnimation = document.getElementById('cube').animate( cubeRotating, cubeTiming ) cubeAnimation.pause(); document.body.onclick = () => ;
In the above example, we're triggering only one animation but you could imagine something more complex where you could trigger and pause multiple animations at once easily.
Other methods are also available such as finish
, cancel
and reverse
.
We can also directly change the playback rate to modify the speed of the animation.
var cubeAnimation = document.getElementById('cube').animate( cubeRotating, cubeTiming ) document.body.onclick = () => { cubeAnimation.playbackRate *= 1.5; };
The code sample above results in making the cube rotate faster on click.
So far, we've seen how to create separate animations and changing their playback but another feature available is the access to all animations at once.
Manipulating all animations
The Web Animations API also has a method called getAnimations
that gives us access to all animations declared with the API.
This way, if we wanted to slow down everything when users have set prefers-reduced-motion
, we could do something like this:
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); if(mediaQuery.matches){ document.getAnimations().forEach(animation => { animation.playbackRate *= 0.5; }) }
In the code sample above, we look for the media query prefers-reduced-motion, and if it is set to 'reduce', we get all animations on the page and set their playback rate to half their normal speed.
This is one of the thing that makes this API so exciting, changes can be made to multiple animations quite easily by changing one property!
Dependencies
Another powerful feature is the ability to make some animation properties dependent on others.
For example, if we now have 2 cubes and we want one of them to rotate twice as fast as the first one, we could write it two different ways:
The first one would be like this:
var cube1Animation = document.getElementById('cube').animate( cubeRotating, { duration: 1000, iterations: Infinity } ); var cube2Animation = document.getElementById('cube2').animate( cubeRotating, { duration: 500, iterations: Infinity } );
The duration of the 1st animation is 1s and the duration of the second is 500 milliseconds.
However, if we write it this way, when we change the duration of the rotation of the first cube, we need to remember to go and change the duration of the second one as well.
You can see how this could become a problem with more complex animations or with more elements being animated.
The nicer way to write this would be to make the rotation of the 2nd cube dependent on the first one, and you can do it like this:
var cube1Animation = document.getElementById('cube').animate( cubeRotating, { duration: 1000, iterations: Infinity } ); var cube2Animation = document.getElementById('cube2').animate( cubeRotating, { duration: cube1Animation.effect.timing.duration / 2, iterations: Infinity } );
This way, we are using the duration set on the 1st cube, divided by 2, so we can make sure that no matter how we change the duration property, the 2nd cube will always rotate twice as fast!
Performance
In terms of performance, I haven't been able to see much difference between using CSS animations and the Web Animations API but that could be because my example is pretty small.
From what I understand, one big advantage is that, compared to other ways of animating using JavaScript, the WAAPI runs on the compositor, so we're letting the main thread forget about animations and deal with the rest of our code.
Browser compatibility
The Web Animations API is currently at a Working Draft status and is partially supported in the latest versions of Firefox and Chrome as well as on the major mobile browsers. However, it seems to be under consideration for Edge and can be enabled via the experimental features on Safari.
At the moment, partial support means that browsers cover functionalities such as play
, pause
, reverse
, finish
, and playbackRate
but do not support yet features such as getAnimations
.
If you'd like, there's also a polyfill available for browsers that don't support the API yet.
That's it for now!
Even though it is still at an experimental stage, the browser support has been growing over the past few years so we can hope that it will soon be fully supported.
I'm personally excited to see how it will impact how developers create and manipulate animations on the web.
If you want to look further into it, here are a few resources:
- Using the Web Animations API
- Web Animations API examples
- Great series "Let's talk about the Web Animations API" by Dan Wilson
Thanks!
This content originally appeared on JavaScript January and was authored by Emily Freeman
Emily Freeman | Sciencx (2020-01-11T14:17:00+00:00) Exploring the Web Animations API. Retrieved from https://www.scien.cx/2020/01/11/exploring-the-web-animations-api/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.