Introduction
This article is seventh in the series of 12 articles that will take us through
learning HTML5 and CSS3, specifically learning about Canvas and its uses through
development of simple games called "Balloon Bob" and
"Bobby Carter"
This article would introduce the below concepts and use them in our game alongside.
Background
The articles related to basics of HTML and CSS will help understanding this article
better. Below are the links.
-
Beginning with HTML and CSS - Part 1/12 - Writing your First Code
-
Beginner's Guide to HTML5 & CSS3 - Part 2 of 12 - By James Jensen
-
Beginning with HTML and CSS - Part 3/12 - Styling Your First Web Page
-
Beginning with HTML and CSS - Part 4/12 - Laying Out Your First Web Page
-
Beginning with HTML and CSS - Part 5/12 - Getting Fancy with CSS3 Animations
and Effects
-
Beginner's Guide to HTML5 and CSS3 - Formidable Forms with HTML5 (Series
6 of 12) - By Ranjan.D

What is Canvas ?
The Canvas element was introduced as part of HTML 5 to enable us to dynamically
render 2D images. The drawing is created via scripting using languages like Javascript.
Some of the usual implementations include creating games, drawing graphs, making
photo compositions, creating animations or even do real-time video processing or
rendering. Today we will learn about Canvas by creating a simple Game on a web page.
Canvas element is a resolution dependent bitmap canvas, it basically is a rectangle
where we can use scripting to draw anything we like or want. If you are thinking
how this element would look, then the answer is “nothing”. Canvas
element in itself has no content or border. An example of creating a Canvas is as
below.
<canvas id="mycanvas" width="100" height="100">Your Browser Doesn’t support Canvas Element</canvas>
With the ID attribute each canvas in the page can be identified via scripts like
any other HTML elements and also each of the canvas on the page maintains its own
state. The text between the Canvas tags is only displayed when the browser doesn’t
recognize and support the Canvas element.
Browser Support:
Most of the modern browsers support the canvas element and below is a quick list
of versions that this element was supported from.
- Internet Explorer (9.0+)
- Safari (3.0+)
- Firefox (3.0+),
- Chrome (3.0+)
- Opera (10.0+)
- iOS (1.0+)
- Android (1.0+)
If you need to implement Canvas in IE with version less than 9 then there is
a very nice solution called
Explore Canvas.
And that’s it we created a Canvas on our page
Before we go any further let me tell you about the game we are going to build
today because we are going to learn as much as possible about Canvas through building
this game here.
The game is a simple breakout game. We would have some Balloons on the top section
of our Canvas and a Trampoline below. We will need to bounce our Bob to break as
many Balloons as possible. What better use in a game with Bob’s pointed head isn’t
it . That’s it. Let’s call this game “Balloon Bob”
Let’s look at some concepts that need to be understood to build some graphics.
2D rendering Context:
The 2D Rendering Context or just the 2D context is part where we draw our shapes.
When we say drawing on a Canvas we infact would be drawing on a context or in this
case 2D rendering context which of course is accessible through the Canvas element.
The canvas element in itself doesn’t provide any properties or methods to draw.
The getContext() method returns an object that provides methods and properties
for drawing on the canvas.
This is all there is to know about this 2D Context, but it’s important to know
as without the context we cannot complete our game
Canvas Co-ordinates:
In our previous article we learnt a lot about x’s, y’s and z’s. Well, that’s
good because we can reuse some of that knowledge now. When drawing on a paper we
essentially are drawing on a 2D plain or a 2D context. The 2D rendering context
we are going to use is not much different, it uses the standard Cartesian coordinate
system, below is a quick diagram of a 2D context with some points represented. Our
Canvas basically is the 4th Quadrant where both x and
y values are positive. Each unit of X and Y should be one pixel on our rendering
screen in most cases.

Let’s take the first Step in our game creation and create a Canvas.
<div style="width:100%;height:100%;text-align:center">
<canvas id="BalloonBob" ></canvas>
</div>
Remember one thing, Canvas always have to be defined with dimensions because
by default it only gets a dimension of 300px * 150px (width * height). Using CSS
to control the dimension property will only result in Canvas being scaled to those
measurements. So let’s give 800px of width and 600px of Height. This means while
drawing, our x can have a max value of 800 and y a value of 600.
<div style="width:100%;height:100%;text-align:center">
<canvas id="scene" width="800" height="600" ></canvas>
</div>
Paths:
In a simple language, Paths on Canvas are a series of points with drawing instructions
between those points.
Paths are used to create shapes including lines on a Canvas. With this you might
already have understood that Path is VERY important. At any given time there can
only be one Path on a Canvas.
Below are the key path functions.
- beginPath()
- closePath()
- moveTo(x, y)
- lineTo(x, y)
- rect(x, y, width, height)
- arc(x, y, radius, starting Angle, ending Angle, anticlockwiseFlag)
- quadraticCurveTo(ctrlPtx, ctrlPty, x, y)
- bezierCurveTo(ctrlPt1x, ctrlPt2y, ctrlPt2x, ctrlPt2y, x, y)
- arcTo(xa, ya, xb, yb, radius)
We might not use all of these in our game but let’s quickly go over what these
are.
If any of you have used
LOGO (Logic Oriented
Graphic Oriented) before and still remember TURTLE and its movements
then it will come handy because drawing on canvas is no different than drawing in
LOGO language.
Before we start on the path functions we need to learn about a function by name
stroke().
The stroke() function :
This function actually draws the path we have defined with all those moveTo()
, lineTo , rect and closePath() methods. The default color is black and can be changed
with a context property by name strokeStyle which takes color/gradient/pattern as
its value. For now let’s use colors and will cover the gradient and patterns later.
Syntax: context.strokeStyle=color|gradient|pattern;
A Path on Canvas is started and ended with the beginPath() and closePath() functions.
The beginPath() function:
This function starts a new path always by clearing out any existing
path. We will see the meaning and uses of this function shortly.
The closePath() function:
closes the path by drawing a line from the current position back to the initial
position. For Example to draw a square you could draw three sides and close the
path which will in turn draw the fourth line.
The moveTo(x, y) function:
This moves our position to the given coordinates without drawing a line.
The lineTo(x, y) function:
This draws a line from whatever the current are to those specified in the arguments.
The rect(x, y, width, height) function:
This draws a rectangle at the X/Y coordinates that you give with the given width
and height. Unloke fillRect() and strokeRect() functions this function only adds
to the current path and does not paint on to the canvas immediately .Nothing is
drawn until you call stroke() or fill().
The above ones are the simplest ones so I will try to cover them all in one example
below.
Example:
The below code is first creating a Canvas by name myCanvas with width 250 and
height 250, we are also adding a border so we can see where the canvas is.
Then we are adding a script section in which we are first getting the canvas
Element through which we will obtain our context called ctx.
- Step1: Beginning the path
- Step2: We are drawing a rectangle with x:20, y:20, height:100 and
width:150.
- Step3: Moving to x:40 and y:20
- Step4: Drawing a line from the current position to x:40 and y:120
- Step5: Setting our stroke style to Green
- Step6: closing the path and calling the stroke method which will
create the above paths (Rectangle and a line)
- Step7: We are repeating steps similar to above to draw a rectangle
next but we are using the closePath() method to draw the last line.
<html>
<body>
<canvas id="HTMLCanvas" width="600" height="600" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas element. Please reopen the page in a supported browser</canvas>
<script>
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.rect(20,20,150,100);
bobContext.moveTo(40,20);
bobContext.lineTo(40,120);
bobContext.strokeStyle = "green";
bobContext.closePath();
bobContext.stroke();
bobContext.beginPath();
bobContext.moveTo(120,120);
bobContext.lineTo(120,200);
bobContext.strokeStyle = "RED";
bobContext.lineTo(170,200);
bobContext.closePath();
bobContext.stroke();
</script>
</body>

The arc(x, y, radius, startingAngle, endingAngle, anticlockwise) function:
Arc function is used to draw a circle or a half circle (ARC) of a give radius(3rd
argument), the middle point is the X,Y (1st and 2nd arguments). The startingAngle
and endingAngle are the angles at which the arc begins and ends.
The angles are measured in Radians and not degrees. A simple formula to calculate
your radians in to divide your degrees by (180/Pi). Pi is approximately 3.14 and
in Javascript we can use the constant Math.PI.
The Angle 0 is on the right side, which is the 3o clock position on a circle
and the last argument anticlockwise dictates how the line will be drawn, this wouldn’t
matter if we are drawing a full circle but when we are not then we will have to
use anti clockwise to get your desired arc at the desired position.

Simple example below.
We are first drawing a full circle and some half circle with anticlockwise value
true and false.
<script>
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.strokeStyle = "red";
bobContext.arc(60,75,50,0,2*Math.PI);
bobContext.stroke();
bobContext.closePath();
bobContext.beginPath();
bobContext.strokeStyle = "green";
bobContext.arc(60,125,40,1.2*Math.PI,1.8*Math.PI);
bobContext.stroke();
bobContext.closePath();
bobContext.beginPath();
bobContext.strokeStyle = "green";
bobContext.arc(180,75,50,1.2*Math.PI,1.8*Math.PI,false);
bobContext.stroke();
bobContext.closePath();
bobContext.beginPath();
bobContext.strokeStyle = "green";
bobContext.arc(300,75,50,1.2*Math.PI,1.8*Math.PI,true);
bobContext.stroke();
</script>

The quadraticCurveTo(cpx, cpy, x, y) function:
This function helps draw a quadratic curve. The origin position will be whatever
position we currently are in and the end postion would be the second two coordinates
given, the first two coordinates will be used as the control point.
A control point is what defines the curvature of aquadratic curve. It does so
by creating two imaginary tangential lines which are connected to the origin point
and the ending point. The origin point nothing but the current position we would
be in, we can move to the right position using the moveto method.
Sharper curves are created by defining farther control points and Broader ones
by defining them much closer.
Syntax: context.quadraticCurveTo(ctrlptx,ctrlpty,x,y);
Example1:
This will not create a curve as our control point is on the original path
var c=document.getElementById("HTMLCanvas");
var bobCtx=c.getContext("2d");
bobCtx.beginPath();
bobCtx.moveTo(5,1); bobCtx. quadraticCurveTo(5,5,5,9); bobCtx.stroke();

Example2:
var c=document.getElementById("HTMLCanvas");
var bobCtx=c.getContext("2d");
bobCtx.beginPath();
bobCtx.moveTo(5,1); bobCtx. quadraticCurveTo(9,6,5,9); bobCtx.stroke();

Example3:
var c=document.getElementById("HTMLCanvas");
var bobCtx=c.getContext("2d");
bobCtx.beginPath();
bobCtx.moveTo(5,1); bobCtx. quadraticCurveTo(9,2,5,9); bobCtx.stroke();

The bezierCurveTo(ctrlpt1x, ctrlpt1y, ctrlpt2x, ctrlpt2y, x, y) function:
This function helps draw a bezier curve. The origin point would be whatever position
we are currently in and the end poistion would be the fifth and sixth coordinates
speified. The first 4 coordinates are used as the control points.
Bezier curves are defined with the origin point, two control points, and an ending
point.
As you can see the differece between quadratic curves and Bezier curves is the
number of Control points used. The former uses one control point where as the latter
uses with two control points. This helps us create more advanced curves.
- The first curve is tangential to the line that can be drawn between the
originpoint and the first control point.
- The second curve is tangential to the line that can be drawn between the
second control point and the ending point.
Syntax: context.bezierCurveTo(ctrlpt1x,ctrlpt1y,ctrlpt2x,ctrlpt2y,x,y);
Examples:
Example1: No change as the Control points are on the path
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.moveTo(5,1); bobContext bezierCurveTo(5,5,7.5,5,5,1); bobContext.stroke(); bobContext bezierCurveTo(5,5,7.5,5,5,1);
Example2:
var c=document.getElementById(HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.moveTo(5,1); // Create a origin point
bobContext.bezierCurveTo(9,6,9,8,5,1); // Create a Path
bobContext.stroke(); // Draw it
Example3:
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.moveTo(5,1); bobContext bezierCurveTo(9,2,1,8,5,1); bobContext.stroke();
Below is GIF image that shows the results of all three examples above.

The arcTo(x1, y1, x2, y2, radius) function:
This method mostly is a combination of ARC and Quadratic Curve functionality.
Like the arc() method this one draws similar arcs using the current position as
the start point with the given radius to [xb, yb] using [xa, ya] as a control point.
Synatax: context.arcTo(xa,ya,xb,yb,r);
Example:
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
bobContext.beginPath();
bobContext.moveTo(20,20); bobContext.lineTo(100,20); bobContext.arcTo(150,20,150,70,50); bobContext.lineTo(150,120); bobContext.stroke();
Alright..!! Now that we have understood the paths in Canvas, let’s start creating
the shapes we need for our Game.
We already created a rectangle (800/600) Canvas above, time to start drawing
on our canvas using the Script.
Creating a Trampoline for Bob to Jump on :
Our Trampoline will just be a rectangle. Before creating the Trampoline some
quick Javascript setup for easy code reading. We will have the below Global Variables
and you will see how we would use them as we go along. We shall call our Canvas
drawArea and our Context as BobContext.
var drawArea, BobContext;
var gameHandle = 0;
var bRightBut = false;
var bLeftBut = false;
var objBob, objTrampoline, objTargetBalloons;
var playPoints = 0;
var tickTock;
var playTime = iMin = iSec = 0;
var prevTickTock, prevScore;
var curvature = (4 * (Math.sqrt(2) - 1)) / 3;
var w_factor = 0.0333;
var h_factor = 0.4;
var tie_w_factor = 0.12;
var tie_h_factor = 0.10;
var tie_curve_factor = 0.13;
var grad_factor = 0.3;
var grad_rad = 3;
var bob = new Image();
var refreshRate = 10;
var clickCounter = 1;
var refreshCounter = 0;
var hitX = -1;
var hitY = -1; var hitRad = -1;
We will also create a class for Trampoline so it would be easier to access its
properties.
function Trampoline(x, w, h) {
this.x = x; this.w = w; this.h = h; }
Clear method:
function clear() {
BobContext.clearRect(0, 0, BobContext.canvas.width, BobContext.canvas.height);
BobContext.fillStyle = '#fff';
BobContext.fillRect(0, 0, BobContext.canvas.width, BobContext.canvas.height);
}
Since we need to animate this game we will refresh our screen every 10 milliseconds
and during this refresh we will redraw our shapes in their new positions to create
the illusion of movement.
To refresh screen every so unit of time Java script provides two easy methods.
They are explained below.
The setInterval and clearInterval Methods
The setInterval method
This method executes specified method every specified milliseconds. This method
returns a var which will be the handle of this timer which will be used to pause
or stop the timer later.
Syntax: var1 = setInterval("javascript_method",milliseconds);
The clearInterval method
This method needs a handle that was received when we kicked off the timer and
using that it would stop the timer and there will not be any new executions after
that.
Syntax: clearInterval(var1)
We will also need to capture our keyboard keypress and mouse. We will use the
below functions to capture the movements of the mouse within the Canvas area and
also Key press events only if the keys pressed are either a Left Arrow or a Right
Arrow.
$(window).keydown(function (event) { switch (event.keyCode) {
case 37: bLeftBut = true;
break;
case 39: bRightBut = true;
break;
}
});
$(window).keyup(function (event) { switch (event.keyCode) {
case 37: bLeftBut = false;
break;
case 39: bRightBut = false;
break;
}
});
var iCanvX1 = $(drawArea).offset().left;
var iCanvX2 = iCanvX1 + width;
$('#scene').mousemove(function (e) { if (e.pageX > iCanvX1 && e.pageX < iCanvX2) {
objTrampoline.x = Math.max(e.pageX - iCanvX1 - (objTrampoline.w / 2), 0);
objTrampoline.x = Math.min(BobContext.canvas.width - objTrampoline.w, objTrampoline.x);
}
});
If you see the above code you will notice that the Mouse Move event is directly
changing the Trampoline X value, so when we refresh the screen every 10 milliseconds
we would have our Trampoline drawn at the new x location. This way you will get
a feeling that the trampoline is responding to Mouse movement in real time. And
as you might have already guess the Y position of trampoline will be constant always.
Also for the keyboard events we are setting two vars called butLeft and butRight
based on what key was pressed. We are going to used these conditions in our refresh
method to recalculate our Trampoline X value. For instance if the left key was pressed
then we will Move our Trampoline to the left by subtracting 50 px from its current
X value.
Now let’s come to the Crux of our game. The refreshScreen method, this is where
we would put all our drawing, calculation and logic. For now let’s create this method
only to capture Trampoline’s position and draw the same accourding to the mouse
movements and key press.
function refreshScreen() {
clear();
if (bRightBut)
objTrampoline.x += 5; else if (bLeftBut)
objTrampoline.x -= 5; BobContext.fillStyle = '#000';
BobContext.beginPath();
BobContext.rect(objTrampoline.x, BobContext.canvas.height - objTrampoline.h, objTrampoline.w, objTrampoline.h);
BobContext.closePath();
}
Another two methods below to set the timer on load and call the above refreshScreen
method every 10 milliseconds. The above Mouse and keyboard events will go into the
init() method
$(function () {
init();
});
function init() {
drawArea = document.getElementById('scene');
BobContext = drawArea.getContext('2d');
BobContext.clearRect(0, 0, drawArea.width, drawArea.height);
var width = drawArea.width;
var height = drawArea.height;
objTrampoline = new Trampoline(width / 2, 120, 8); gameHandle = setInterval(refreshScreen, refreshRate); $(window).keydown(function (event) { switch (event.keyCode) {
case 37: bLeftBut = true;
break;
case 39: bRightBut = true;
break;
}
});
$(window).keyup(function (event) { switch (event.keyCode) {
case 37: bLeftBut = false;
break;
case 39: bRightBut = false;
break;
}
});
var iCanvX1 = $(drawArea).offset().left;
var iCanvX2 = iCanvX1 + width;
$('#scene').mousemove(function (e) { if (e.pageX > iCanvX1 && e.pageX < iCanvX2) {
objTrampoline.x = Math.max(e.pageX - iCanvX1 - (objTrampoline.w / 2), 0);
objTrampoline.x = Math.min(BobContext.canvas.width - objTrampoline.w, objTrampoline.x);
}
});
}
That’s it, below is a GIF image showing how this will look now.

Let’s make some Balloons, for this we shall you’re the Bizier Curve method.
Below a Baloon class.
function Balloon(centerX, centerY, radius, color) {
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius * .85;
this.baseColor = color;
}
And a method to draw the Balloon. I have added comments inside the code to make
it easier to understand.
Balloon.prototype.draw = function () {
var centerX = this.centerX;
var centerY = this.centerY;
var radius = this.radius;
var handleLength = curvature * radius; var widthDiff = (radius * w_factor); var heightDiff = (radius * h_factor); var balloonBottomY = centerY + radius + heightDiff;
BobContext.beginPath();
var topLeftCurveStartX = centerX - radius;
var topLeftCurveStartY = centerY;
var topLeftCurveEndX = centerX;
var topLeftCurveEndY = centerY - radius;
BobContext.moveTo(topLeftCurveStartX, topLeftCurveStartY);
BobContext.bezierCurveTo(topLeftCurveStartX, topLeftCurveStartY - handleLength - widthDiff,
topLeftCurveEndX - handleLength, topLeftCurveEndY,
topLeftCurveEndX, topLeftCurveEndY); var topRightCurveStartX = centerX;
var topRightCurveStartY = centerY - radius;
var topRightCurveEndX = centerX + radius;
var topRightCurveEndY = centerY;
BobContext.bezierCurveTo(topRightCurveStartX + handleLength + widthDiff, topRightCurveStartY,
topRightCurveEndX, topRightCurveEndY - handleLength,
topRightCurveEndX, topRightCurveEndY); var bottomRightCurveStartX = centerX + radius;
var bottomRightCurveStartY = centerY;
var bottomRightCurveEndX = centerX;
var bottomRightCurveEndY = balloonBottomY;
BobContext.bezierCurveTo(bottomRightCurveStartX, bottomRightCurveStartY + handleLength,
bottomRightCurveEndX + handleLength, bottomRightCurveEndY,
bottomRightCurveEndX, bottomRightCurveEndY); var bottomLeftCurveStartX = centerX;
var bottomLeftCurveStartY = balloonBottomY;
var bottomLeftCurveEndX = centerX - radius;
var bottomLeftCurveEndY = centerY;
BobContext.bezierCurveTo(bottomLeftCurveStartX - handleLength, bottomLeftCurveStartY,
bottomLeftCurveEndX, bottomLeftCurveEndY + handleLength,
bottomLeftCurveEndX, bottomLeftCurveEndY); BobContext.fillStyle = this.baseColor;
BobContext.fill();
var halfTieWidth = (radius * tie_w_factor) / 2;
var tieHeight = (radius * tie_h_factor);
var tieCurveHeight = (radius * tie_curve_factor);
BobContext.beginPath();
BobContext.moveTo(centerX - 1, balloonBottomY);
BobContext.lineTo(centerX - halfTieWidth, balloonBottomY + tieHeight);
BobContext.quadraticCurveTo(centerX, balloonBottomY + tieCurveHeight,
centerX + halfTieWidth, balloonBottomY + tieHeight);
BobContext.lineTo(centerX + 1, balloonBottomY); BobContext.fill();
}
Now that we have the Balloon class and its draw method lets go ahead and create
a Balloon with some 100 radius at 100,100 (x,y). Let’s choose the color Orange
var balloon1 = new Balloon(100, 100, 100, 'FF9900'); balloon1.draw(0);
Below is how it would look.

Yeah..!! It sure looks like a balloon but doesn’t really have the real Balloon
look, does it?
To achieve that, HTML provides us with methods to create Gradients.
Gradient is similar to what we learnt in our previous article about CSS gradients.
We have two Gradient methods for Canvas namely LinearGradient and RadialGradient.
createLinearGradient():
This method creates a gradient object. However, defining a gradient doesn’t draw
anything on the canvas. It’s just an object stored in memory. To apply a gradient,
you set your fillStyle to the gradient object created above and draw a shape, like
a rectangle or a line.
Syntax: context.createLinearGradient(x1,y1,x2,y2);
Create Linear Gradient Arguments
Argument |
Description |
x1 |
This is the x-coordinate value of the start of the gradient |
y1 |
This is the y-coordinate value of the start of the gradient |
x2 |
This is the x-coordinate value of the end of the gradient |
y2 |
This is the y-coordinate value of the end of the gradient |
However, we will also need to add color stops to really get our gradient effect.
We will have to use the below method to do so.
addColorStop():
This method specifies the colors and position in a gradient object.
Syntax: gradient.addColorStop(stop,color);
Here the gradient is the object we created earlier using the createLinearGradient
method.
Stop is a value between 0.0 and 1.0. Using these values we can define as many
colors as we want on our gradient. Let’s look at an example which creates a Rainbow
like gradient and applies it to a rectangle.
var c=document.getElementById("HTMLCanvas");
var bobContext=c.getContext("2d");
var grd=bobContext.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"black");
grd.addColorStop("0.3","magenta");
grd.addColorStop("0.5","blue");
grd.addColorStop("0.6","green");
grd.addColorStop("0.8","yellow");
grd.addColorStop(1,"red");
bobContext.fillStyle=grd;
bobContext.fillRect(10,10,200,100);
Result will be as below

createRadialGradient():
This method creates a Radial or a circular gradient instead of a linear pattern
Syntax: context.createRadialGradient(x1,y1,r1,x2,y2,r2);
Create Radial Gradient Arguments
Argument |
Description |
x1 |
This is the x-coordinate value of the start of the gradient |
y1 |
This is the y-coordinate value of the start of the gradient |
r1 |
The radius of the outermost circle |
x2 |
This is the x-coordinate value of the end of the gradient |
y2 |
This is the y-coordinate value of the end of the gradient |
r2 |
The radius of the innermost circle |
Like the linear Gradient even the Radial gradient will need a defined set of
color stops.
So let’s use the above example and just change the linear gradient to Radial
gradient by adding the radius. Radius 100 will define the outermost radius for the
color defined at 1.0 stop and 10 will be the radius of the inner most color at 0.0
color stop.
var grd=bobContext.createRadialGradient(100,50,100,100,50,10);
And below will be the result. Since the radius of Black is 100 it has gone out
of our rectangle which is not big enough to hold the whole gradient.

So now for our Balloon let’s use the Radial Gradient. All we need to do is apply
darker base color on the outer edge and lighten is gradually as we move inward.
To get the lighter and Darker Color let’s use the below method which returns
the lighter or Darker color code based on the value between 0 and 1 we pass.
function ColorLuminance(hex, lum) {
hex = String(hex).replace(/[^0-9a-f]/gi, '');
if (hex.length < 6) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
lum = lum || 0;
var rgb = "#",
c, i;
for (i = 0; i < 3; i++) {
c = parseInt(hex.substr(i * 2, 2), 16);
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
rgb += ("00" + c).substr(c.length);
}
return rgb;
}
And in our Balloon class lets add some data members to hold these lighter and
darker color codes
function Balloon(centerX, centerY, radius, color) {
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius * .85;
this.baseColor = ColorLuminance(color, 0);
this.darkColor = ColorLuminance(color, -0.3);
this.lightColor = ColorLuminance(color, 0.3);
}
Our Draw method should now create a gradient and apply the same to the balloon
var gradientOffset = (radius / 3);
var balloonGradient =
BobContext.createRadialGradient(centerX + gradientOffset, centerY - gradientOffset,
grad_rad,
centerX, centerY, radius + heightDiff);
balloonGradient.addColorStop(0, this.lightColor);
balloonGradient.addColorStop(0.7, this.darkColor);
BobContext.fillStyle = balloonGradient;
BobContext.fill();
That’s it. Let’s see how our Balloon looks now.

Viola!! Now, we are talking. That looks like a 3D image than a 2D image, isn’t it
?
Since we need to have more balloons to target lets create an Array to hold all
these Balloons and draw them next to each other in 5 rows. So our Array would be
5 rows and how many ever columns we can fit. Below is the TargetBalloons class that
will hold an arraj of Balloon objects.
function TargetBalloons(w, h, r, c, p) {
this.w = w;
this.h = h;
this.r = r; this.c = c; this.p = p; this.objs; this.colorCode; this.colors = ['9d9d9d', 'f80207', 'feff01', '0072ff', 'fc01fc', '03fe03', 'FF9900', '99CC00', '99FFFF', '330033', 'fff']; }
Lets fill this array in our Init() method.
objTargetBalloons = new TargetBalloons((width / 8) - 1, 20, 6, 8, 2); objTargetBalloons.objs = new Array(objTargetBalloons.r); objTargetBalloons.colorCode = new Array(objTargetBalloons.r);
for (i = 0; i < objTargetBalloons.r; i++) {
objTargetBalloons.objs[i] = new Array(objTargetBalloons.c);
objTargetBalloons.colorCode[i] = new Array(objTargetBalloons.c);
for (j = 0; j < objTargetBalloons.c; j++) {
objTargetBalloons.objs[i][j] = 1; objTargetBalloons.colorCode[i][j] = Math.ceil(Math.random() * 11); }
}
As the next step we will have to loop through this array and create our balloons
inside our refreshScreen method.
for (i = 0, k = 25; i < objTargetBalloons.r; i++) {
if (k == 0)
k = 25; else
k = 0;
for (j = 0; j < objTargetBalloons.c; j++)
{
var balloon1 = new Balloon(k + (j * (objTargetBalloons.w + objTargetBalloons.p)) + objTargetBalloons.p + objTargetBalloons.w / 4, (i * (objTargetBalloons.h + objTargetBalloons.p)) + objTargetBalloons.p, objTargetBalloons.w / 2, objTargetBalloons.colors[objTargetBalloons.colorCode[i][j]]);
balloon1.draw();
}
}
}
}
Since we now know about gradients lets also apply a linear Gradient to our Trampoline
var trampolineGradient = BobContext.createLinearGradient(objTrampoline.x, BobContext.canvas.height - objTrampoline.h,
objTrampoline.x + objTrampoline.w, (BobContext.canvas.height - objTrampoline.h));
trampolineGradient.addColorStop(0, "gray");
trampolineGradient.addColorStop(0.5, "white");
trampolineGradient.addColorStop(1.0, "gray");
BobContext.fillStyle = trampolineGradient;
We have a beautiful screen filled with Balloons.

Now that we have the stage ready let’s give our Bob a welcome to enter the arena
to assist us bursting these balloons.
To draw images on canvas HTML provides a drawImage() method.
DrawImage():
As we saw earlier this method is used to draw images on Canvas. So without much
ado let’s just straight into syntax and examples.
This method can take 3, 5 or 9 arguments.
drawImage(image, x, y) : This is the simplest of all
the methods which takes a image and draws it at given x and y coordinates. The x
and y will be the upper-left corner of the image. Values of x,y = (0, 0) would draw
the image at the upper-left corner of the canvas. This will also draw the image
at its original resolution
drawImage(image, x, y, w, h): This method does the
same thing as above but it would scale the image down or up to the given width[w]
and height[h].
drawImage(image, clipX, clipY, clipW, clipH, x, y, scaleW, scaleH)
: This method takes an image, clips it to the rectangle (clipX, clipY,
clipW, clipH), scales it to dimensions (scaleW, scaleH), and draws it on the canvas
at coordinates (x, y).
Example:
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
var bob = new Image();
cat.src = "images/bob.png";
context.drawImage(bob, sx=2, sy=2, sw=3, sh=3, dx,=4 dy=4, dw=4, dh=4)
Below is a representation of how the above example would be rendered

But what if you need to repeat your images all over canvas ?
For instance you need to create a background with images for your canvas you
can do a loop to draw the same image over and over again until you fill the canvas.
Well, HTML has a more easier and elegant approach.
It provides a method called createPattern() which repeats a
specified element in a specified direction. In our case this element will be an
image.
Syntax: context.createPattern(image,"repeat-value");
Parameter
|
Description
|
image
|
Defines the element which can be aimage, canvas, or avideo element that
will be used for the pattern
|
Repeat-value
|
This parameter defines the repeating direction of the pattern on canvas.
Below are the values that this parameter takes
repeat
|
This is the default value and it repeats the element both horizontally
and vertically
|
repeat-x
|
The pattern repeats the element only horizontally
|
repeat-y
|
The pattern repeats the element only vertically
|
no-repeat
|
The pattern will display the element only once
|
|
Let’s quickly look at an example of creating a background with a small image
which repeats both Horizantally and vertically.
Let’s add a variable called imgBG(image Background) and assign a image to the
same in our init() method.
var imgBG = new Image();
imgBG.src = 'images/pattern.jpg';
And in our clear() method lets draw this image using createPattern() and drawimage()
methods every time we finish clearing the screen.
function clear() {
BobContext.clearRect(0, 0, BobContext.canvas.width, BobContext.canvas.height);
var BGpattern = BobContext.createPattern(imgBG, 'repeat');
BobContext.rect(0, 0, drawArea.width, drawArea.height);
BobContext.fillStyle = BGpattern;
BobContext.fill();
}
The result will look something like below

Time to get Bob into our canvas. Below is the class to hold Bob’s positions
function Bobby(x, y, dx, dy, r) {
this.x = x; this.y = y; this.dx = dx; this.dy = dy; this.r = r; }
In our Init method lets instantiate a obj of the Bobby class and call the object
objBob, for now our dx and dy will be 0 and radius will be 10. Bob’s initial position
will bottom-centre of the Canvas.
objBob = new Bobby(width / 2, 550, 0, 0, 10);
In the refresh screen let’s actually draw Bob.
BobContext.drawImage(bob, objBob.x, objBob.y, 50, 50);
And now our screen will look like below

So we got most of the stuff done. Only thing now is to bounce Bob around and
detect collisions with the wall and trampoline.
Below is the code which will detect collisions and change the dx and dy values
so that bobby will be created at a new position on every refresh
First thing lets kick off Bob’s movement by giving a small dx and dy values while
creating Bob’s object in the init() method.
objBob = new Bobby(width / 2, 550, 0.5, -5, 10);
Now in our refreshscreen() method lets do some collision detection.
iRowH = objTargetBalloons.h + objTargetBalloons.p;
iRow = Math.floor(objBob.y / iRowH);
iCol = Math.floor(objBob.x / (objTargetBalloons.w + objTargetBalloons.p));
if (objBob.x + objBob.dx + objBob.r > BobContext.canvas.width || objBob.x + objBob.dx - objBob.r < 0) {
objBob.dx = -objBob.dx;
}
if (objBob.y + objBob.dy - objBob.r < 0) {
objBob.dy = -objBob.dy;
} else if (objBob.y + objBob.dy + objBob.r > BobContext.canvas.height - (objTrampoline.h + 25)) {
if (objBob.x > objTrampoline.x && objBob.x < objTrampoline.x + objTrampoline.w) {
objBob.dx = 10 * ((objBob.x - (objTrampoline.x + objTrampoline.w / 2)) / objTrampoline.w);
objBob.dy = -objBob.dy;
} else if (objBob.y + objBob.dy + objBob.r > BobContext.canvas.height) {
clearInterval(gameHandle); }
}
objBob.x += objBob.dx;
objBob.y += objBob.dy;
Notice that we have code in such a way that if Bob hits left half of the trampoline
them we are creating an angled movement towards left of the canvas and similary
to the right when he hits the right side. Below is the condition that does that.
objBob.dx = 10 * ((objBob.x - (objTrampoline.x + objTrampoline.w / 2))/ objTrampoline.w);
Our Bob’s jumping around in joy.. You can see how happy he is below.

The last part is to burst the balloons when hit. And it’s pretty simple because
all we have to do is set the value of the balloon array element to 0 when hit. Since
we have the balloons created in 8/5 grids its easy to detect if Bob has enetered
that area and if yes just set the active value of that [i][j] to 0.
Below is the code. Let’s also create a var called playPoints and keep incrementing
the same whenever a Balloon is hit.
// Burst Balloon if hit and reverse Bob's direction
if (objBob.y < objTargetBalloons.r * iRowH && iRow >= 0 && iCol >= 0 && objTargetBalloons.objs[iRow][iCol]
== 1) {
objBob.dy = -objBob.dy; //reverse y direction of Bob
playPoints++; //Increase the score by one
objTargetBalloons.objs[i][j] = 0; //Set the active value of the Balloon value to
0 so that the Balloon will not be created when refreshing the next time in another
10 milliseconds
}
Sounds good, but let’s also experiment with some more methods of canvas namely
Translate, Rotate and Scale.
Translate, Rotate and Scale methods
Translate
Just like in CSS even in Canvas Translate is used to move objects by x and y
values. However, translate on a canvas means moving the whole canvas by the x and
y value and anything drawn after the translate will be draw on the new canvas with
a shift by x and y values.
Syntax: context.translate(x,y);
Example: Below is a quick representation of how a translate works.

Rotate
A simple definition would sound like “Rotate method rotates the canvas by a given
angle”
Just like the translate rotate rotates the whole canvas and not the elements.
Also the rangle of values for rotate would between -90 and +90 degrees as anything
beyond that would rotate the canvas into other quadrants and our drawings will not
be visible.
Syntax: context.rotate(angle);
The value of angle should be in radians. As mentioned earlier to convert our
degrees to radians use the below formulae:
Radians = degrees*Math.PI/180.
For instance, to rotate 45 degrees, specify the following: Context.rotate(45*Math.PI/180);
Below is a quick representation of how a rotate works. Notice that anything outside
the canvas(yellow box) is not displayed , the blue lines shows the 45 degree angle
at which the canvas is rotated.

The last method in this section is Scale(x,y).
Scale
This method just like the other two methods impacts the whole canvas and when
used would scale the canvas according to the x and y values. When x=2 and y=2 the
canvas would be scaled to double the original size. Below is a representation of
before and after the scale is applied to a Canvas.
Syntax: Context.scale(x,y);


To avoid all other drawing being shifted after using translate/scale/rotate method
HTML provides two methods to restore the Canvas back to its original state.
Save and restore
Call save() before translate/rotate/scale and restore immediately after translate/rotate/scale
so that ll our drawings after that will be drawn on the normal coordinates and not
the translated/rotated/scaled ones.
Lastly, I would like to discuss about a property and a method related to drawing
text on Canvas, so you can get back to playing with the code to make this game a
even more cooler one
Context.Font
The property is know as font and is applied to a Context. It sets or gets the
font properties for text content on the canvas context.
The syntax is as below and is exactly same as the font property in CSS.
Syntax: context.font=font-style font-variant font-weight font-size font-face;
Example: context.font="italic small-caps bold 12px arial";
FillText() Method
This method is used to create or draw text on Canvas. The default color is black
and if there was a Font property set before calling this method then the same would
be taken into consideration.
Syntax: context.fillText(text,x,y,maxWidth);
Example:
var canvas1=document.getElementById("HTMLCanvas");
var bobContext=canvas1.getContext("2d");
bobContext.font="20px Georgia";
bobContext.fillText("Bob is Jumping!",20,70);
bobContext.font="30px Verdana";
var grd=bobContext.createLinearGradient(0,0,canvas1.width,0);
grd.addColorStop("0","Green");
grd.addColorStop("0.5","Red");
grd.addColorStop("1.0","Blue");
bobContext.fillStyle=grd;
bobContext.fillText("Bob is Jumping!",40,100);
I have used the above methods to move, shrink , rotate a balloon when hit by
Bob and to display score and x,y co-ordinates of Bob when he is bouncing.
I am attaching the final code instead of adding it here to keep the length of
this article under control
. But below is quick GIF image to see how it looks
on screen.
I have also added some functionality to pause on a single click on Canvas and
a button to restart the game anytime. You may want to try adding multi lives for
a single game and even multiplayer functionality.

As an assignment lets create a simple game called Bobby Carter
Our Bob has a new job now to collect all the carts on canvas.
However, as he collects the carts he has to pull them behind him and the cart
train gets longer. The objective is to collect as many carts as possible without
hitting his own cart train.
Try this and if you get stuck, you can download the solution attached at the
top of this article.
Below is how my solution resulted in, due to time constrain it looks very simple
but you are welcome to play with the code and make it better and cooler.

Using the code
Three simple steps to download, load and start playing the Game. The Java script
files had most of the code and are located in the Script Sub folders of each Game.
- Download
- Unzip
- Open the HTML in Chrome (I haven't tested this on other browers. Hence,
would recommend Chrome)
Points of Interest
I sure learnt one thing. Creating a GAME is much more fun than Playing one. I
am sure you will feel the same too.
I would also like to thank the author,
Franken Logan
for helping me create perfect Balloons.
History
Initial creation of the article - Guru prasad K Basavaraju - 4/27/2014