You can get additional control over animations — as well as useful information about them — by making use of animation events. These events, represented by the AnimationEvent
object, can be used to detect when animations start, finish, and begin a new iteration. Each event includes the time at which it occurred as well as the name of the animation that triggered the event.
We'll modify the sliding text example to output some information about each animation event when it occurs, so we can get a look at how they work.
Adding the CSS
We start with creating the CSS for the animation. This animation will last for 3 seconds, be called "slidein", repeat 3 times, and alternate direction each time. In the @keyframes
, the width and margin-left are manipulated to make the element slide across the screen.
.slidein {
animation-duration: 3s;
animation-name: slidein;
animation-iteration-count: 3;
animation-direction: alternate;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
Adding the animation event listeners
We'll use JavaScript code to listen for all three possible animation events. This code configures our event listeners; we call it when the document is first loaded in order to set things up.
const element = document.getElementById("watchme");
element.addEventListener("animationstart", listener, false);
element.addEventListener("animationend", listener, false);
element.addEventListener("animationiteration", listener, false);
element.className = "slidein";
This is pretty standard code; you can get details on how it works in the documentation for eventTarget.addEventListener()
. The last thing this code does is set the class
on the element we'll be animating to "slidein"; we do this to start the animation.
Why? Because the animationstart
event fires as soon as the animation starts, and in our case, that happens before our code runs. So we'll start the animation ourselves by setting the class of the element to the style that gets animated after the fact.
Receiving the events
The events get delivered to the listener()
function, which is shown below.
function listener(event) {
const l = document.createElement("li");
switch (event.type) {
case "animationstart":
l.textContent = `Started: elapsed time is ${event.elapsedTime}`;
break;
case "animationend":
l.textContent = `Ended: elapsed time is ${event.elapsedTime}`;
break;
case "animationiteration":
l.textContent = `New loop started at time ${event.elapsedTime}`;
break;
}
document.getElementById("output").appendChild(l);
}
This code, too, is very simple. It looks at the event.type
to determine which kind of animation event occurred, then adds an appropriate note to the <ul>
(unordered list) we're using to log these events.
The output, when all is said and done, looks something like this:
- Started: elapsed time is 0
- New loop started at time 3.01200008392334
- New loop started at time 6.00600004196167
- Ended: elapsed time is 9.234000205993652
Note that the times are very close to, but not exactly, those expected given the timing established when the animation was configured. Note also that after the final iteration of the animation, the animationiteration
event isn't sent; instead, the animationend
event is sent.
Just for the sake of completeness, here's the HTML that displays the page content, including the list into which the script inserts information about the received events:
<h1 id="watchme">Watch me move</h1>
<p>
This example shows how to use CSS animations to make <code>H1</code>
elements move across the page.
</p>
<p>
In addition, we output some text each time an animation event fires, so you
can see them in action.
</p>
<ul id="output"></ul>
And here's the live output.
Note: Reload page to see the animation.