In the last post, we saw the easy way to animate a DOM element by using the new element.animate
method. This is useful if you want to play simple animations on a single element, but what if you want to create more complex animations involving multiple elements? Sure, you could set up event listeners to listen for one animation to finish to start the next, but there’s a better way.
The WAAPI includes three objects that can be used to create more complex animation effects: KeyframeEffect
, GroupEffect
, and SequenceEffect
. I’m only going to look at KeyframeEffect
in this post, but know that it will be used with the other two later.
Unfortunately, as of June 2017, attempting to use KeyframeEffect
s puts us firmly in polyfill territory. It can be found on github or on npm.
Creating a KeyframeEffect
If you’re already familiar with the WAAPI, this section can be skipped. Otherwise, lets see how to make a keyframe effect.
To create the KeyframeEffect
, we use the new KeyframeEffect
constructor available in the browser. The syntax for creating one is as follows:
const theEffect = new KeyframeEffect(elementToAnimate, keyframes, timingOptions);
Then, to run it we will create a new animation using this effect. The animation constructor takes two arguments: the KeyframeEffect and a timeline. With the animation created, we can then use the animation methods (play
, pause
, reverse
, etc.) to control playback.
const theAnimation = new Animation(theEffect, document.timeline);
theAnimation.play();
KeyframeEffect and React
Now that we know how to make a playable animation with KeyframeEffect
, it’s pretty straightforward to make a basic animation in a react component.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import 'web-animations-js/web-animations-next.min.js';
class AnimatedDiv extends Component {
constructor() {
super();
this.toggleAnimation = this.toggleAnimation.bind(this);
}
componentDidMount() {
if(!this.ref) return;
let effect = new KeyframeEffect( this.ref, [{opacity:0},{opacity:1}], {duration: 500, fill:'both'} );
this.animation = new Animation(effect, document.timeline);
this.animation.play();
}
toggleAnimation() {
if (this.animation) this.animation.reverse();
}
render() {
return (
<div style={{
height: 100,
width: 100,
background: 'blue'
}}
ref={(r) => this.ref=r}
onClick={this.toggleAnimation}>
</div>
);
}
}
ReactDOM.render(<AnimatedDiv />, document.getElementById('app'));
Easy, right? In the next post, we’ll look at how to play multiple KeyframeEffect
s at the same time using GroupEffect
s. See you then!