Skip to content
October 24, 2012 / geeksretreat

Great Balls of Gravity – HTML5 Canvas

Continuing with the Physics posts my second post on the subject involves mimicking the gravity effect on a medicine, basket, football and tennis balls.   A working version can be viewed here. The completed project is depicted below:

Falling balls effect in HTML5's canvas

The example above uses the Canvas element which is available in most of the major browsers as part of HTML5. The mark up of the above follows:
<!--<span class="hiddenSpellError" pre=""-->DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>Canvas Ball Animation</title>
		<script src='ball.js'></script>
	</head>
	<body onload='init();'>
		<canvas id="canvas" width="1000" height="600">Canvas Not Supported</canvas>
		<div style="display: none;">
			<img id='cannonballImage' src='cannonball.png'/>
			<img id='basketballImage' src='basketball.png'/>
			<img id='footballImage' src='football.png'/>
			<img id='tennisballImage' src='tennisball.png'/>
		</div>
	</body>
</html>
The mark is fairly lean, the main elements are the script tag, the onload event on the body tag, and the hidden div tag which holds the following images:

HTML5 gravity effect with different balls

The gravity effect is implemented within the JavaScript source code. The source code resides in the file which the browsers loads when it handles the script tag:
	<script src='ball.js'></script>
The entry point into the JavaScript is within the onload event of the body tag:
	<body onload='init();'>
The source code within the ‘init’ function as the title indicates initialises the animation effect:

function init() {

    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');

    setUpBalls();
    loadBackground();

}
The ‘init’ function simply obtains a handle to the canvas tag and then obtains its context which is required to draw. These two variables are defined in a global scope and are used throughout the code. The second step within the function is the call to the ‘setupBalls’ function:
function setUpBalls() {

    var iBallTop,
        i,
        ball = null,
        x = 0;

    while(x < 950) {

        iBallTop = (0 - Math.floor((Math.random() * 400) + 1));
        ball = getRandomBallSettings(iBallTop);

        balls.push(new Ball(x, ball));

        x += ball.width + 10;
    }

}
This function moves along the x axis and creates a ball object until the horizontal space is filled. The main elements within this function are the call to the ‘getRandomBallSettings’ and the push action on the balls array. The function call simply creates an object which holds various settings required to create a new ball object. The content of this is as follows:
function getRandomBallSettings(iBallTop) {

    var iImageRnd = Math.floor((Math.random() * 4) + 1),
        ballImage = {
                        image: null,
                         bounce: null,
                         top: iBallTop,
                         height: 90,
                         width: 90
                    };

    if(iImageRnd === 1) {

        ballImage.image = document.getElementById("basketballImage");
        ballImage.factor = 0.8;
        ballImage.height = 50;
        ballImage.width = 50;

    } else if(iImageRnd === 2) {

        ballImage.image = document.getElementById("footballImage");
        ballImage.factor = 0.7;
        ballImage.height = 45;
        ballImage.width = 45;

    } else if(iImageRnd === 3) {

        ballImage.image = document.getElementById("tennisballImage");
        ballImage.factor = 0.6;
        ballImage.height = 20;
        ballImage.width = 20;

    } else {

        ballImage.image = document.getElementById("cannonballImage");
        ballImage.factor = 0.35;
        ballImage.top = -460;
        ballImage.height = 60;
        ballImage.width = 60;

    }

    return ballImage;

}
The function starts by obtaining a random number between 1-4. This number is then used to determine which ball should be created. Various attributes are set, theses represents properties such are the image’s height, width and bounce factor. The settings object is then returned to the calling interface. Returning to the ‘setUpBalls’ function, the settings object is then used to create a ball object which inturn is added to the balls array as follows:
	balls.push(new Ball(x, ball));
The ball object is fundamental to the process. Each object created represents a single ball; thus, it must include the necessary attributes to draw the ball in the correct position. This includes attributes such as the ball type: e.g. basket, tennis, football or, medicine ball. The code which represents the ball object follows:
var Ball = function(x, ballSettings) {

    this.vy = 0;
    this.vx = 0;

    this.vyAdjust = -13;

    this.width = ballSettings.width;
    this.height = ballSettings.height;

    this.x = x;
    this.y = ballSettings.top;
    this.image = ballSettings.image;
    this.bounceFactor = ballSettings.factor;

    //Function to draw it
    this.draw = function() {

        ctx.drawImage(this.image,
            this.x, this.y,
            this.width, this.height);

    };

    this.impact = function() {

        this.vy = this.vyAdjust;

    };

    this.move = function() {

        this.y += this.vy;
        this.vy += gravity;

        // Bounce the ball when it hits the bottom
        if ((this.y + this.height) > canvas.height - 10) {

            this.impact();

            this.vyAdjust = (this.vyAdjust * this.bounceFactor);
        }

    };

};
The object is fairly simple. It create the object using the settings object which is passed in during the construction phase. The object also includes three functions. These are used to draw the ball, instigate the bounce and move the ball accordingly to the gravity and bounce factor variables. Once each ball is created it is added to the balls array: the animation can then start.

function loop() {

    update();
    requestAnimFrame(loop);

}

This function is called iteratively. It calls the ‘update’ function and then requests the next animation frame: and repeats. The update function performs the necessary actions to move and redraw the balls:

function update() {

    var i;

    clearCanvas();

    drawBackground();

    for (i = 0; i < balls.length; i++) {

        balls[i].move();
        balls[i].draw();

    }
}

The function simple clears the canvas and draws the gym scene as the background. It then iterates through each ball within the balls array. Each individual ball is then first moved and then redrawn. This combination is what replicates the bounce effect.
That concludes this post. A working version can be viewed here. The source code is available in Github.
About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 172 other followers

%d bloggers like this: