Javascript Animation Example Using requestAnimFrame, Basic Trigonometry & HTML5 Canvas – Part 1

Just playing around with animating HTML5 Canvas elements with Javascript. I started with this basic horizontally moving rectangle, then added some trig code to move multiple objects around in a circle. Here’s a demo.

If the Math.sin() & Math.cos() is confusing, watch the video tutorials on Trig and Unit Circle in particular at the Khan Academy.

<!DOCTYPE HTML>
<html>
    <head>
        <style>
            body {
                margin: 0px;
                padding: 0px;
            }
            
            #myCanvas {
                border: 1px solid #9C9898;
            }
        </style>
        <script>
            var numsqr = 40;
            var mShapes = [];

            window.requestAnimFrame = (function(callback){
                return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                window.msRequestAnimationFrame ||
                function(callback){
                    window.setTimeout(callback, 1000 / 60);
                };
            })();
            
            function drawRect(myRectangle){
                var canvas = document.getElementById("myCanvas");
                var context = canvas.getContext("2d");
                context.beginPath();
                context.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height);
                
                context.fillStyle = "#8ED6FF";
                context.fill();
                context.lineWidth = myRectangle.borderWidth;
                context.strokeStyle = "black";
                context.stroke();
            }
            
            function animate(lastTime,  mShapes, animProp){
                if (animProp.animate) {
                    var canvas = document.getElementById("myCanvas");
                    var context = canvas.getContext("2d");
                    
                    // update
                    var date = new Date();
                    var time = date.getTime();
                    var timeDiff = time - lastTime;
        
                    for(var j = 0; j < numsqr; j++){
                        
                        //circles around a midpoint in a larger circle, specified by the radius                              
                        mShapes[j].x = mShapes[j].centerX + Math.cos( mShapes[j].angle * Math.PI/180 ) * mShapes[j].radius;   
                        mShapes[j].y = mShapes[j].centerY + Math.sin( mShapes[j].angle * Math.PI/180 ) * mShapes[j].radius; 

                        (mShapes[j].angle < 360) ? mShapes[j].angle += 1 : mShapes[j].angle = 0;      
                    }                            
                    lastTime = time;
                    
                    // clear
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    
                    // draw                    
                    for(var l = 0; l < numsqr; l++)
                       drawRect(mShapes[l]);                    
                    
                    // request new frame
                    requestAnimFrame(function(){
                        animate(lastTime,  mShapes, animProp);
                    });
                }
            }
            
            window.onload = function(){

                 for(var i = 0; i < numsqr; i++){                     
                     mShapes[i] = {
                        angle:0,
                        width:20,
                        height:20,
                        x: 100 + i*10,
                        y: 250,
                        centerX: 290,
                        centerY: 290,      
                        radius: 250 - (1 + i * 5),            
                        borderWidth: 1
                    };
                 }
                    
                /*
                 * make the animation properties an object
                 * so that it can be modified by reference
                 * from an event
                 */
                var animProp = {
                    animate: false
                };
                
                // add click listener to canvas
                document.getElementById("myCanvas").addEventListener("click", function(){
                    if (animProp.animate) {
                        animProp.animate = false;
                    }
                    else {
                        animProp.animate = true;
                        var date = new Date();
                        var time = date.getTime();
                        animate(time,  mShapes, animProp);
                    }
                });
              
                for(var k = 0; k < numsqr; k++)
                     drawRect( mShapes[k] );   
                 
            };
        </script>
    </head>
    <body onmousedown="return false;">
        <canvas id="myCanvas" width="600" height="600"></canvas>
    </body>
</html>