The Web Animation API has been around for several years. Its goal is to combine the performance of CSS3 animations, the flexibility of JavaScript, and as much Animation control as possible with native browsers. Provides a generic way to animate DOM elements using JS.

1, the introduction

The recent development of the project involves the animation part, and the number and complexity are not low, if the way of CSS processing is indeed feasible, but CSS animation has no direct exposure to the time method, you need to encapsulate their own to grab the end of the callback. At this time, I consider whether there is a KIND of JS control suitable for complex logic Animation, so I found the Web Animation API, which can use JS to directly manipulate the browser Animation engine.

2. Usage and case comparison

For example, the animate method accepts two parameters: Keyframes and options, where keyframes corresponds to the declaration block in @KeyFrames in CSS3, and options corresponds to the animation-* property and its value. WebAnimation is an Animation object that contains several methods:

const element = document.querySelector('.animate');
const webAnimation = element.animate(keyframes, options);
Copy the code

The keyframes and options inputs and the animate methods are described below.

Keyframes parameters

The first parameter keyframes means keyframes, which is usually an array of objects, each of which is a frame in the animation. Used to specify the timeline of an animation’s style changes at key points. Here is a simple example of keyframes.

const keyframes = [
    { opacity: 1 },
    { opacity: 0}];Copy the code

As shown above, the animation changes the transparency of an element from 1 to 0. Another way is to pass in an Object Object, where each Key represents the CSS property of the animation we want to set, and the corresponding value property is the animation processing to be done. Each element in the value represents the first time point in the animation’s timeline.

const keyframes = {
    opacity: [1.0]}Copy the code

If you use CSS syntax to create a timeline of the same utility, it looks like this:

@keyframes keyframes {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0; }}Copy the code

As you can see, although they are grammatically different, there is still a slight similarity in writing. By default, each node on the timeline is divided by equal duration. For example, if we put 10 nodes on a timeline, the duration of each node automatically equals 10% of the total time.

Of course, in CSS we often specify the duration manually to control the required animation length, as in the CSS syntax creation example:

@keyframes keyframes {
    0% { opacity: 1 }
    10% { opacity: 0.7 }
    40% { opacity: 0.3 }
    70% { opacity: 0.7 }
    100% { opacity: 0}}Copy the code

It can be seen that the Animation is a variable speed effect, which is not lost in the Web Animation API. The system provides the offset attribute, whose value can be set to any number from 0 to 1, which is equivalent to converting percentages into decimals in CSS syntax. The CSS timeline above can be implemented by merging offset with the previous creation:

const keyframes = [
    { opacity: 1 },
    { opacity: 0.7.offset: 0.1 },
    { opacity: 0.3.offset: 0.4 },
    { opacity: 0.7.offset: 0.7 },
    { opacity: 0},]Copy the code

The effect is basically the same, understanding is also more clear and easy to understand.

The options parameter

The options value of the.animate() function can be used in two ways. The first is to pass a duration in milliseconds, as in the following:

element.animate([
    { opacity: 1 },
    { opacity: 0}].1000);
Copy the code

As you can see, 1000 milliseconds is passed in the options field, which means that the animation will be completed in 1000 milliseconds. This way is suitable for some simple, configuration is not complex animation, you can only specify the time.

In the second way, options are passed with more complete configuration items, such as slow mode, whether to loop, etc. Here is a complete list of configuration items:

const options = {
    // Animation execution times
    iterations: Infinity.// Start time of animation
    iterationStart: 0.// A delay before the animation starts
    delay: 0.// A delay after the animation ends
    endDelay: 0.// Whether the animation plays backwards in the next cycle
    direction: 'alternate'.// Animation length
    duration: 1000.// Keep the state before and after the animation
    fill: 'forwards'.// Animation slow type
    easing: 'ease-in-out',
}
element.animate(keyframes, options);
Copy the code

Based on these configuration items, a looping animation can be completed without delay. If you’re familiar with animation, you’ll notice that these properties look a little like CSS, but a little different. Some properties, such as delay or duration, become CSS properties with an animation- prefix. Here is a simple comparison table listing some of the similar attributes:

Web Animation API properties CSS properties
delay animation-delay
duration animation-duration
iterations animation-iteration-count
direction animation-direction
easing animation-timing-function
fill animation-fill-mode

With that in mind, create a CSS animation and try to rewrite it in JS style. For example, the start delay of the following is one second, and the duration of the Animation is also one second. Meanwhile, the Animation executed in an infinite loop can be implemented in the same way by using the Web Animation API.

.animate-test {
    animation-name: keyframes;
    animation-duration: 1s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-delay: 1s;
}
Copy the code

Is equivalent to

const testOptions = {
    duration: 1000.iterations: Infinity.direction: 'alternate'.delay: 1000
}
Copy the code

The animate method

An animation is implemented by calling the animate method on the element and passing in the KeyFrames timeline and the configuration item Options as parameters. The animate method also provides a number of handy functions to call to control animations:

const element = document.querySelector('.animate');
const webAnimation = element.animate(keyframes, options);
// Animation pauses
webAnimation.pause();
// Start animation
webAnimation.play();
Copy the code

In addition to basic methods such as pausing, there are.cancel() to cancel the animation and.reverse() to reverse the animation.

The finished event can be used as a Promise to solve problems in CSS animation that are difficult to catch, inaccurate in time, and require a lot of wrapping.

webAnimation.finished.then(() = > {
    element.remove();
})
Copy the code

3. Precautions

Similarities and differences in sentences

Options in.animate() can be passed in as a configuration item object, either different configuration options or a duration. It is the same as the familiar CSS variable, but slightly different.

  • More commonly used in CSSsThat is seconds, which is preferred in JSmsMilliseconds, also used in the Web Animation API.
  • If you want the animation to keep looping, it will be used in CSSanimation-iteration-countProperty, the value isinfinite. But in theoptionsIs used initerations, the property value isInfinity, pay attention to the spelling differences, andInfinityIs a JavaScript keyword, not a string.
  • The default CSS3 easing type isease.animate()The default easing type islinearLinear.

API compatibility

Compatibility is also a problem we must pay attention to in the development of animation, sometimes in the development process, often because of compatibility and adaptation problems have to give up some methods or attributes, or the original way “curve implementation”. Or introduce the corresponding polyfill to downgrade.

How about the compatibility of Web Animation API? You Can find more detailed information on Can I Use website:

As you can see, API native compatibility is still quite poor, with versions supported in multiple browsers either high or not fully supported, especially on mobile. This is not what we would like to see, but there is also a Polyfill library for compatibility problems, which can be installed directly through NPM, or you can import the following JS files:

<script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
Copy the code

With the addition of Polyfill, you can worry a little less about compatibility.

Performance and comparison

According to the data I reviewed, the performance gap between CSS3 and The Web Animation API is not particularly significant in most cases. However, for individual properties, the two have their own advantages. For example, when the transform or opacity property is used, the Web Animation API will call a thread other than the main thread of the browser to render the Animation, which will have more advantages in performance. At the same time the logic is complicated, with some random processing of the animation is also more suitable for JS implementation.

4, summarize

My feelings about CSS animations in development are obvious. For example, some values need to change dynamically, it is very inconvenient to maintain the same animation effect scattered in different files, and the timing of timers is not accurate enough. Of course, these pain points may be my art is not fine, but also to explore.

Usually rely on the third party library development is the choice of many people, but in some of the performance volume requirements of the project or a little pursuit of their own technology, it is not appropriate to rely on the imported library. When a JS native solution is needed, the Web Animation API comes into play.