Choosing when to use JavaScript for animations

The CSS3 animations and transitions created a way for modern browsers to recognize what animations are. They also created a way for modern browsers to differentiate animations from other operations so that they can use the Graphics Processing Unit (GPU) to accelerate the hardware of the animation instead of the Central Processing Unit (CPU), which receives all other operations.

Another advantage of using CSS transitions and animations instead of JavaScript is the fact that JavaScript runs on a browser's main thread. CSS animations enable browsers to run operations on new threads and create different layers, which are separated from everything else happening on the main thread. In other words, while your main UI thread will be in heavy use, JavaScript animations might freeze although CSS animations will continue to work.

Note

CSS3 animations, CSS3 transitions, and JavaScript animations that use requestAnimationFrame are the best options in order to avoid the poor performance of animations.

Nowadays, web apps run on devices too, and browsers can stop CSS3 animations when the app is in the background tab, resulting in improved battery life. This is just one of the possibilities for the browser to improve its performance. In Chapter 8, Animations' Performance Optimization, we will see how to optimize an animation's performance.

Check out high performance animations.

Here, we see one example of animation that can be easily created with CSS3 as well as JavaScript.

The HTML code for the page is as follows:

<!DOCTYPE html>
<html>
<head>
    <title>Getting Started</title>
    <link href="animations.css" rel="stylesheet" />
</head>
<body>
    <div>
        <h1>Animation with JavaScript</h1>
        <!--There is a click listener for this button -->
        <button id="jsBtn">Click here to move the element below with JS</button>
        <div id="jsanimation">
            This block will be moved by JavaScript
        </div>
        <h1>Animation with jQuery</h1>
        <!--There is a click listener for this button -->
        <button id="jQBtn">Click here to move the element below with jQuery</button>
        <div id="jQanimation">
            This block will be moved by jQuery
        </div>
        <h1>Animation with CSS3 transition</h1>
        <!--There is a click listener for this button -->
        <button id="cssBtn">Click here to move the element below with CSS3 transition</button>
        <div id="csstransition">
            This block will be moved by CSS3 transition
        </div>
        <h1>Animation with CSS3 animation</h1>
        <!--There is a click listener for this button -->
        <button id="cssAnimationBtn">Click here to move the element below with CSS3 animation</button>
        <div id="cssanimation">
            This block will be moved by CSS3 animation
        </div>
    </div>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="animations.js"></script>
</body>
</html>

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

The declarative way to animate is CSS. In CSS, we defined the translate transform for objects with the .move-to-right class. This declaration makes the move but does not create the animation between the moves. We declared how the div element to be moved should be transitioned; it should last 2 seconds and be slow towards the start and end.

The animations.css CSS file is as follows:

/* Code used by JavaScript animation sample */
#jsanimation {
    position: relative;
}

/* Code used by jQuery animation sample */
#jQanimation {
    position: relative;
}

/* Code used by CSS Transition animation sample */
#csstransition {
    position: relative;
    /* Here we should add -moz-transition, -webkit-transition, -o-transition for browsers compatibility, we will explain about vendor prefixes later */
    transition: all 2s ease-in-out;
}

.move-to-right {
    /* Here we should add vendor prefixes too */
    transform: translate(100px,0);
}

/* Code used by CSS Animation sample */
#cssanimation {
    position: relative;
}

@-webkit-keyframes move-to-right-animation {
    from {
        left: 0px;
    }

    to {
        left: 100px;
    }
}

@keyframes move-to-right-animation {
    from {
        left: 0px;
    }

    to {
        left: 100px;
    }
}

.move-to-right-animation {
    position: relative;
    left: 100px;
    /* Here we should add -moz-animation, -o-animation for browsers compatibility*/
    -webkit-animation: move-to-right-animation 1s ease-in-out;
    animation: move-to-right-animation 1s ease-in-out;
}

The animations.js JavaScript file is as follows:

/* Code used by JavaScript animation sample */
var jsAnimationElement = document.getElementById('jsanimation');
var jsAnimationBtn = document.getElementById('jsBtn');
/**
* Listener of the "Click here to move the element below with JS" button
*/
jsAnimationBtn.addEventListener('click', function moveBtnClickListener() {
    //This variable holds the position left of the div
    var positionLeft = 0;

    /**
    * function that moves jsAnimationElement 10px more to right until the positionLeft is 100
    */
    function moveToRight() {
        positionLeft += 10;

        /* Set position left of the jsanimation div */
        jsAnimationElement.style.left = positionLeft + 'px';

        if (positionLeft < 100) {
            /* This recursive function calls itself until the object is 100px from the left, every 100 milliseconds */
            setTimeout(moveToRight, 100);
        }
    }

    moveToRight();
}, false);

/* Code used by jQuery Animation sample */
/**
* Listener of the "Click here to move the element below with jQuery" button
*/
$("#jQBtn").click(function () {
    /** Use the jQuery animate function to send the element to more 100px to right in 1s */
    $("#jQanimation").animate({
        left: "+=100"
    }, 1000);
});

/* Code used by CSS transition animation sample */
var cssTransitionElement = document.getElementById('csstransition');
var cssTransitionBtn = document.getElementById('cssBtn');
/**
* Listener of the "Click here to move the element below with CSS3" button
*/
cssTransitionBtn.addEventListener('click', function moveCssBtnClickListener() {
    /* Add class "move-to-right" to the block on button click */
    cssTransitionElement.classList.add('move-to-right');
});

/* Code used by CSS Animation sample */
var cssAnimationElement = document.getElementById('cssanimation');
var cssAnimationBtn = document.getElementById('cssAnimationBtn');
/**
* Listener of the "Click here to move the element below with CSS3" button
*/
cssAnimationBtn.addEventListener('click', function moveCssAnimationBtnClickListener() {
    /* Add class "move-to-right" to the block on button click */
    cssAnimationElement.classList.add('move-to-right-animation');
});

This code shows you four approaches for the same animation. The intention is to move a div element 100 px to the right smoothly. This is not the AngularJS way to create animations, but before you learn how to create an animation with AngularJS, you should know all the options.

First we created an animation with JavaScript without requestFrameRate. The result is not so good, and its code is not so pretty. The second animation uses jQuery animate; the code is simpler than the JavaScript version, is imperative, and the result is OK. The third animation uses the CSS transition; it's very clean code with a great and smooth result, declarative way. The fourth animation uses the CSS animation with the same result as the transition version. It made the animation declarative and a little more powerful than the transition, as we can add frames between 0 percent and 100 percent of the animation, although the code is bigger. At this time of writing this, it's necessary to use the -webkit- vendor prefix for the animation to work, even for Chrome.

Although CSS3 animations and transitions have huge advantages, they have disadvantages as well. Creating complex, combined animations is still hard or impossible in order to achieve a good result. In cases like these, JavaScript animations are a better option. JavaScript animations are an option for fallback too when transitions and CSS animations aren't available, which is a common scenario when your project supports old browsers.

A good website that will help you know which browsers have support for CSS animations and transitions is http://caniuse.com.