JavaScript > Timer

requestAnimationFrame in JavaScript

How to create animations in JavaScript?


requestAnimationFrame

requestAnimationFrame is an method in JavaScript {requestAnimationFrame() method}, which tells the browser to perform animation as per the requests that the browser executes a specified function to update an animation before the next level of animation.

Whenever we need to update the animation on screen we call the requestAnimationFrame() method. This method can be handled in many ways such as setInterval() method or setTimeout() method. This method provides a smoother animation on the screen, this is because of using a consistent frame rate.

In JavaScript, by using requestAnimationFrame() method we can create animations.

Moving colored portion on the window.

<style>
        #myId {
            position: fixed;
            left: 10px;
            width: 100px;
            height: 50px;
            padding: 1em;
            background: lightgreen;
            color: #441515;
            font-size: medium;
            text-align: center;
        }
</style>

<p id="myId">Click here to move</p>

    <script>
        var a = document.getElementById('myId'),
     startTime = null,
     EndPosition = 2000, //* in pixels *//
     TimeSpeed = 1000; //* in milliseconds *//

        function myFunction(time) {
            if (time === undefined) {
                time = new Date().getTime(); //* getTime() returns only time part from the new Date() *//
            }
            if (startTime === null) {
                startTime = time;
            }

            a.style.left = ((time - startTime) / TimeSpeed * EndPosition % EndPosition) + 'px';
        }

        a.onclick = function () {
            (function myAnimation() {
                myFunction();
                requestAnimationFrame(myAnimation, a);
            })();
        };
    </script>

In the above code snippet there are 3 type of codes, they are CSS code, HTML code & JavaScript Code, CSS code which is kept in <style> block gives style to the HTML content and the script block is for animation functioning.

We need to move the colored portion on the window, for that in the script block we have given document.getElementById("myId"), which returns the element that has Id "id=myId" in the HTML page, and there is new Date().getTime() returns the current time portion from the new Date() method.

We haven't give start animation time, so startTime = null , EndPosition = 2000 indicates the moving colored portion end part on window, and TimeSpeed = 1000 indicates the 1 second time given for moving the coloured portion on window.

There is a function myAnimation() which is connceted to the requestAnimationFrame() along with the a variable. Onclick the colored portion start animation and the colored portion moves until close the tab/window. 

OUTPUT

Filling the window with the squares.

    <style>
        #myId {
            background: lightgreen;
        }
    </style>

    <canvas id="myId"></canvas>

    <script>
        var a = {
            canvas: document.getElementById("myId"),
            ctx: document.getElementById("myId").getContext('2d'),

            //* Suqares size *//
            xd: 0,
            yd: 0,

            //* Squares drwaing position *//
            pX: 0,
            pY: 0,

            repeat: 0, //* requestAnimationFrame *//

            divisions: 30, // breaks frame into X × X squares

            init: function () {

                // Set up "Two Dimensional" Array to remember what is on and off
                this.memory = new Array(this.divisions - 1);
                for (var i = 0; i < (this.divisions + 1) ; i++) {
                    this.memory[i] = new Array(this.divisions - 1);
                }

                // Size the canvas appropriately
                var width = window.innerWidth;
                var height = window.innerHeight;
                fill.canvas.width = width;
                fill.canvas.height = height;

                // Size of squares is canvas width broken into equal chunks
                fill.xd = width / a.divisions;
                fill.yd = height / a.divisions;

                //* Orange color//
                this.ctx.fillStyle = "#ff8040";

                // Random starting position
                this.pX = Math.floor(Math.random() * this.divisions);
                this.pY = Math.floor(Math.random() * this.divisions);

                // global
                drawLoop = function () {
                    a.repeat = requestAnimationFrame(drawLoop);
                    a.oneMovement();
                }
                drawLoop();

            },

            drawSquare: function (x, y) {
                a.ctx.fillRect(x * this.xd, y * this.yd, this.xd, this.yd);
                a.memory[x][y] = true;
            },

            checkPossiblePositions: function () {
                var posToReturn = [];
                if (this.pX == 0) {
                } else if (this.memory[this.pX - 1][this.pY] == true) {  //* left not allowed *//
                } else {
                    posToReturn.push("left"); //* left covered *//
                }
                if (this.pX == this.divisions) {  //* right side not allowed *//
                } else if (this.memory[this.pX + 1][this.pY] == true) {
                } else {
                    posToReturn.push("right");   //* right side occupied *//
                }
                if (this.pY == 0) {
                } else if (this.memory[this.pX][this.pY - 1] == true) {    //* Top side not allowed *//
                } else {
                    posToReturn.push("up");  //* top covered *//
                }
                if (this.posY == this.divisions) {
                } else if (this.memory[this.pX][this.pY + 1] == true) {  //* Down side not allowed *//
                } else {
                    posToReturn.push("down");  //* down covered *//
                }

                return posToReturn;

            },

            startNewRound: function () {
                cancelAnimationFrame(this.repeat);
                var newSpot = this.findEmpty();  //* new space for aimation *//

                if (newSpot == "nope") {
                    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);  //* clear animation *//
                    this.init();  //* start from first *//
                } else {
                    this.pX = newSpot[0];  //* Start from new position *//
                    this.pY = newSpot[1];

                    drawLoop();   //* Restart Animation*//

                }
            },

            oneMovement: function () {
                this.drawSquare(this.pX, this.pY);
                var possiblePos = this.checkPossiblePositions();
                var numPossible = possiblePos.length;
                if (numPossible == 0) {
                    this.startNewRound();
                } else {
                    var randomDir = Math.floor(Math.random() * numPossible);
                    if (possiblePos[randomDir] == "left") {
                        this.pX--;
                    }
                    if (possiblePos[randomDir] == "right") {
                        this.pX++;
                    }
                    if (possiblePos[randomDir] == "up") {
                        this.pY--;
                    }
                    if (possiblePos[randomDir] == "down") {
                        this.pY++;
                    }
                }
            },

            findEmpty: function () {
                for (var x = 0; x < (this.divisions + 1) ; x++) {
                    for (var y = 0; y < (this.divisions + 1) ; y++) {
                        if (!this.memory[x][y]) {
                            return [x, y];
                        }
                    }
                }
                return "nope";
            }
        }

        setTimeout(function () { fill.init(); }, 10);
    </script>

Filling the window with squares

We need to full the window with the squares, for that we are using above code snippet with requestAnimationFrame() method. To see the output of the above code snippet, click here.

OUTPUT

Animation with the control buttons.

<style>
        #myId {
            width: 700px;
            background: none;
            padding: 1em;
            margin: 1em auto;
        }
        
        canvas {
            background: #ff6a00;
        }

        button {
            display:inline-flexbox;
            border-radius: 3px;
            border: 2px;
            font-size: 1.5rem;
            padding: 0.5rem 0.9em;
            background: #69c773;
            border-bottom: 1px solid #498b50;
            color: white;
            -webkit-font-smoothing: antialiased;
            font-weight: bold;
            margin: 0 0.30rem;
            text-align: center;
        }

            button:hover, button:focus {
                opacity: 0.9;
                cursor:pointer;
            }

            button:active {
                opacity: 1.2;
                box-shadow: 0 -4px 9px rgba(0, 0, 0, 0.5) inset;
            }
    </style>

    <div id="myId">
        <div class="controls">
            <button type="button" id="startBtn">Start Animation</button>
            <button type="button" id="stopBtn">Stop Animation</button>
            <button type="button" id="resetBtn">Reset</button>
        </div>

        <canvas id="stage" width="590" height="150"></canvas>
    </div>

    <script>
        (function() {
            var lastTime = 0;
            var vendors = ['ms', 'moz', 'webkit', 'o'];
            for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
                window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
                window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                                           || window[vendors[x]+'CancelRequestAnimationFrame'];
            }
 
            if (!window.requestAnimationFrame)
                window.requestAnimationFrame = function(callback, element) {
                    var currTime = new Date().getTime();
                    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
                    var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
                      timeToCall);
                    lastTime = currTime + timeToCall;
                    return id;
                };
 
            if (!window.cancelAnimationFrame)
                window.cancelAnimationFrame = function(id) {
                    clearTimeout(id);
                };
        }());


        (function() {
            var startBtn = document.getElementById('startBtn');
            var stopBtn = document.getElementById('stopBtn');
            var resetBtn = document.getElementById('resetBtn');

            var requestID;

            var canvas = document.getElementById('stage');

            var ctx = canvas.getContext('2d');

            ctx.fillStyle = '#008080';

            var posX = 0;
            var boxWidth = 50;
            var pixelsPerFrame = 5; 

            ctx.fillRect(posX, 0, boxWidth, canvas.height);

            function animate() {
                requestID = requestAnimationFrame(animate);

                if (posX <= (canvas.width - boxWidth)) {
                    ctx.clearRect((posX - pixelsPerFrame), 0, boxWidth, canvas.height);
                    ctx.fillRect(posX, 0, boxWidth, canvas.height);
                    posX += pixelsPerFrame;
                } else {
                    cancelAnimationFrame(requestID);
                }
            }


            startBtn.addEventListener('click', function(e) {
                e.preventDefault();

                requestID = requestAnimationFrame(animate);
            });

            stopBtn.addEventListener('click', function(e) {
                e.preventDefault();
            
                cancelAnimationFrame(requestID);
            });

            resetBtn.addEventListener('click', function(e) {
                e.preventDefault();              
                posX = 0;                
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.fillRect(posX, 0, boxWidth, canvas.height);
            });

        }());
    </script>

Animation with the control buttons

We are creating a animation with the control buttons "Start Animation", "Stop Animation", "Reset" in the requestAnimationFrame() method, anmd also we use the clearTimeout() method to stop the animation timer set.

OUTPUT

 Views: 716 | Post Order: 194



Write for us