I’m getting lots of mileage out of the Web Animations API lately, I’ve been so enthused, I recorded a course on the subject (on Udemy and Skillshare).

If you aren’t familiar with the Web Animations API at all, it’s basically a way to do and write everything you can already do with CSS animations but with some extra super powers, such as sequencing animations and compositing different animations together. The syntax might seem odd at first but once you get used to the pattern you’ll be confident to do anything you did with CSS in JavaScript. And more besides!

For example, rotating an element 180 degrees looks like this:

ele.animate({
    transform: "rotate(180deg)"
}, {
    duration: 300,
    fill: "forwards",
}

The animate method takes two arguments; the keyframes and then the animation options. So that prior JavaScript is the equivalent of writing this in CSS:

@keyframes rotate {
    to {
        transform: rotate(180deg);
    }
}

.ele {
    animation: rotate forwards 300 linear;
}

One simple example use case I came across, that isn’t covered in the course is making something like a ‘Pie Timer’. This is simple and self contained enough that I thought it would be worth sharing as a post.

Here is what I mean by a Pie Timer:

See the Pen Pie Timer with the Web Animations API by Ben Frain (@benfrain) on CodePen.

Simple Pie Timer

There may be more elegant ways to achieve a pie timer effect, but this, in pseudo code is how I envisaged the effect working:

Start with a ‘cover’ segment on the left hand side of the pie, with two further segments directly below. The cover has a background colour equal to whatever colour the pie timer is sitting on — the empty pie if you will. So by default we have an empty circle.

Then we rotate (and animate) those two lower segments, that are identical and sat on top of one another, 180 degrees around the centre point of our pie. This gives you the first part of the pie timer being filled.

Now, we make our ‘cover’ transparent, and immediately rotate one of our already rotated segments back to their starting point — and that completes the pie fill effect.

Why not just CSS?

It’s not that this kind of thing can’t be done with CSS, it’s just that it’s far easier and robust when coded with the JavaScript Web Animations API.

Sequencing animations has to be done semi-manually with CSS currently. Getting the 2nd part of this animation to run at the right time has to be done by using a delay. Right now, in CSS, there is no way to say “when this thing finishes animating, start this next animation”. That’s something you can do with the Web Animations API.

The Web Animations API provides us with .finished.then(() => {}). This is a promise based piece of syntax that does what you probably imagine — waits for one thing to finish and then runs the next. You can how that’s used in this simple animation below.

The JavaScript

So, here is the commented JavaScript code for the pie timer animation, which perhaps makes sense even for the uninitiated?

// Get the elements we need
const outer = document.querySelector(".pie-Outer");
const s1 = document.querySelector(".pie-Segment1");
const s2 = document.querySelector(".pie-Segment2");
const cover = document.querySelector(".pie-Segment_Cover");
const btn = document.getElementById("go");

// How long the timer should take
const duration = 300;

// Fire the function when btn clicked
btn.addEventListener("pointerdown", animPieTimer);

function animPieTimer() {
    // Need to move 2 at once, could have wrapped them in the DOM - Meh
    let firstMoveElements = [s1, s2];
    // If we are running this again, we need to reset things first:
    cover.style.backgroundColor = "#eee";
    firstMoveElements.forEach((ele) => ele.animate({ transform: "rotate(0deg)" }, { duration: 0, fill: "both" }));

    // First spin the two segments together, this gives the first part of the fill
    firstMoveElements.forEach((ele, idx) => {
        ele.animate(
            {
                transform: "rotate(180deg)",
            },
            {
                duration: duration,
                fill: "forwards",
            }
        ).finished.then(() => {
            // On the last iteration, make the 'cover' transparent
            if (idx === firstMoveElements.length - 1) {
                cover.style.backgroundColor = "transparent";
                // Then animate the upper segment back around to complete the fill
                s2.animate(
                    { transform: "rotate(360deg)" },
                    {
                        duration: duration,
                        fill: "forwards",
                    }
                );
            }
        });
    });
}

Summary

You can see in this example how straightforward it is to start running one animation as soon as another animation finishes.

For me, the Web Animations API fills a void between the current shortcomings of CSS animations and the full blown timeline capabilities (and library file size) of something like GreenSock.

Furthermore, as it’s something baked into the Web platform it feels like time worth investing — it’s not going anywhere anytime soon!

If you want more written information on the Web Animations API, the MDN docs, as ever, are excellent. Also, Una Kravets and Kevin Ellis have a good, albeit Chrome-centric, piece on web.dev. And good ol’ CSS-tricks has a bunch or tutorials. Also make sure you check out David K Piano of [@keyframers](https://www.youtube.com/keyframers) fame who is a master of all things Web Animation!

Special mention to Daniel C Wilson who has been writing about the Web Animations API for years — so definitely check his work out!