Thursday, August 10, 2017

JavaScript-Based Animations Using Anime.js, Part 3: Values, Timeline, and Playback

JavaScript-Based Animations Using Anime.js, Part 3: Values, Timeline, and Playback

In the previous tutorial of the Anime.js series, you learned about different kinds of parameters that control how different target elements should be animated. You also learned how to use function parameters to gradually change the delay or duration of the elements. 

In this tutorial we will go a step further and learn how to specify the property values themselves using regular numbers, function-based values, and keyframes. You will also learn how to play animations in sequence using timelines.

Specifying Property Values

Anime.js allows you to specify the final or end values for animatable properties of target elements. The initial or start value for the animation is the default value of that property. Any value specified in the CSS can also act as the start value. There are multiple ways of specifying an end value. 

It can also be a unitless number. In this case, the original or default units of the property are used while calculating any property values. You can also specify the value as a string, but the string must contain at least one numerical value. Examples of string values would be 10vh, 80%, and 9.125turn.

Instead of specifying an absolute value, you can also specify property values relative to their current value. For example, you can set the final translateY value to be 150px greater than the current value using +=150px as a value. Keep in mind that you can only use addition, multiplication and subtraction while specifying relative values.

While animating colors, you cannot use color names like red, black and blue to set a final color value for the animation. In such cases, the color animation won't happen at all, and the change will be instant. The only way to animate colors is to specify the values either as hex digits or in terms of RGB and HSL values.

As you might have noticed, we have not been specifying an initial value for our target elements to animate them. Anime.js automatically determines the initial value based on our CSS and the default values of those properties. However, you can specify an initial value other than the default value for a property using arrays. The first item in the array signifies the initial value, and the second item signifies the final value.

Instead of using the same final value for all your target elements, you can use functions to set different values for different parameters. The process is similar to specifying function-based property parameters.

For the translateY property, we are using the index of the element to set a translation value. Using 50 * (i + 1) increases the translateY value for each element by 50 pixels. 

The scaling animation also uses the index of the element along with the built-in Math.random() function to return a floating-point, pseudo-random number less than 1. This way the elements scale randomly, but the i/10 part of the property slightly increases the possibility of elements that occur in the end having a larger size.

Inside the code for rotation animation, we are using the anime.random(a, b) helper function to get random integers between -180 and 180. This function is helpful for assigning random integral values to properties like translateY and rotate. Using this function to assign random scale values will produce extreme results.

The border radius value for different elements is determined by calculating the width of target elements using the el function parameter. Finally, the last part of code assigns random values to the duration and delay parameters as well. 

You can see that the animation achieved by the last part is very random. There is no relation between the values of different properties of elements or their delay and duration values. In real life, it is more sensible to use values that can add some sense of direction to the animation.

It is also possible to animate different properties of your target elements using keyframes. Each keyframe consists of an array of the property object. You can use the object to specify the property value, duration, delay and easing for that part of the animation. The following code creates a keyframe-based translation animation.

You can also animate multiple properties at once by specifying different or the same values for all the parameters. In the second case, the global delay parameter applies an initial delay to all the elements based on their index. This delay is independent of the delay applied to each property inside the keyframes.

Creating and Manipulating Timelines

So far in the series, we have been using the delay parameter to play different animations in a specific sequence. To use delay for this purpose, we also need to know the duration of the previous animation. 

With the increasing complexity of the animation sequence, maintaining the right delay value becomes very tedious. Any change in the duration of one of the animations will force us to recalculate all the delay values to keep the animations in the original sequence.

A better solution to this problem is using timelines to control the animation sequence. You have to use the anime.timeline() function to create a timeline in Anime.js. You can also pass different parameters to this function as an object. These parameters can specify the direction in which the timeline is played, the number loops, and an autoplay parameter to determine if the animation should be auto-played. All these parameters have been discussed in detail in the parameters tutorial of this series.

You can add different animations to a timeline using the add() method. All the animations added to the timeline will be played in the order in which they were added. It is possible to specify absolute or relative offset values to control the order in which the animations are played. 

When relative offset values are used, the starting time of the current animation is determined relative to the timing of the previous animation. Relative offsets can be of three types:

  • +=offset: In this case, the current animation starts playing after offset number of milliseconds have passed since the end of the previous animation.
  • -=offset: In this case, the current animation starts playing offset number of milliseconds before the end of the previous animation.
  • *=offset: In this case, the current animation starts playing after milliseconds equal to offset times the animation duration of the previous animation have passed.

The following code shows how to create a basic timeline and a timeline with relative offset values.

Try clicking the Offset Timeline button in the above demo. You will see that there is a delay of 2 seconds between the end of the animation of red squares and the beginning of the animation of blue squares. 

We have not specified a duration for the red square animation. Therefore, a default value of 1000ms or 1s is used as duration. The multiplier offset of the blue square animation doubles that value, and this results in a delay of two seconds in the animation.

When absolute offset values are used, the starting time of the timeline is used as a reference point. It is possible to reverse the sequence in which the animations are played by using large offset values for animations that occur at the beginning of the timeline.

Playback Options

Anime.js has a variety of options to play, pause, restart or seek animations or timelines at any given point.

The play() function allows us to start the animation from its current progress. The pause() function will freeze the animation at the moment the function was called. The restart() function starts the animation from the beginning, irrespective of its current progress. The seek(value) function can be used to advance the animation by value number of milliseconds.

You should keep in mind that the play() function only resumes the animation from the time it was paused. If the animation has already reached its end, you cannot replay the animation using play(). To replay the animation, you will have to use the restart() function.

Note that we are not using seekInput.value to set a value for the seek function. This is because the max value for the range input has been set to 100 in the markup. Directly using the value for input range will allow us to only seek up to 100ms. Multiplying the range input value with the animation duration makes sure that we can seek the animation from the beginning to the end on our range slider.

Final Thoughts

In this tutorial, you learned how to animate different property values as numbers, functions, or keyframes. You also learned how to control and manipulate timelines in Anime.js to control the order in which an animation sequence is played.

If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.

If you have any questions related to this tutorial, please let me know in the comments.


No comments:

Post a Comment