Sequencing animations
=====================

* Previous
* Overview: Asynchronous

In this assessment you'll update a page to play a series of animations in a sequence. To do this you'll use some of the techniques we learned in the How to use Promises article.

|  |  |
| --- | --- |
| Prerequisites: | 
 A reasonable understanding of JavaScript
 fundamentals, how to use promise-based APIs.
  |
| Objective: | To test understanding of how to use promise-based APIs. |

Starting point
--------------

Make a local copy of the files at https://github.com/mdn/learning-area/tree/main/javascript/asynchronous/sequencing-animations/start. It contains four files:

* alice.svg
* index.html
* main.js
* style.css

The only file you'll need to edit is "main.js".

If you open "index.html" in a browser you'll see three images arranged diagonally:

![Screenshot of sequencing-animations assessment page](/en-US/docs/Learn/JavaScript/Asynchronous/Sequencing_animations/sequencing-animations.png)

The images are taken from our guide to Using the Web Animations API.

**Note:** If you get stuck, you can reach out to us in one of our communication channels.

Project brief
-------------

We want to update this page so we apply an animation to all three images, one after the other. So when the first has finished we animate the second, and when the second has finished we animate the third.

The animation is already defined in "main.js": it just rotates the image and shrinks it until it disappears.

To give you more of an idea of how we want the page to work, have a look at the finished example. Note that the animations only run once: to see them run again, reload the page.

Steps to complete
-----------------

### Animating the first image

We're using the Web Animations API to animate the images, specifically the `element.animate()` method.

Update "main.js" to add a call to `alice1.animate()`, like this:


```js
const aliceTumbling = [
  { transform: "rotate(0) scale(1)" },
  { transform: "rotate(360deg) scale(0)" },
];

const aliceTiming = {
  duration: 2000,
  iterations: 1,
  fill: "forwards",
};

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");

alice1.animate(aliceTumbling, aliceTiming);
```


Reload the page, and you should see the first image rotate and shrink.

### Animating all the images

Next, we want to animate `alice2` when `alice1` has finished, and `alice3` when `alice2` has finished.

The `animate()` method returns an `Animation` object. This object has a `finished` property, which is a `Promise` that is fulfilled when the animation has finished playing. So we can use this promise to know when to start the next animation.

We'd like you to try a few different ways to implement this, to reinforce different ways of using promises.

1. First, implement something that works, but has the promise version of the "callback hell" problem we saw in our discussion of using callbacks.
2. Next, implement it as a promise chain. Note that there are a few different ways you can write this, because of the different forms you can use for an arrow function. Try some different forms. Which is the most concise? Which do you find the most readable?
3. Finally, implement it using `async` and `await`.

Remember that `element.animate()` does *not* return a `Promise`: it returns an `Animation` object with a `finished` property that is a `Promise`.

* Previous
* Overview: Asynchronous