HTML5 fundamentals, Part 4: The final touch

The canvas

HTML5 reflects the monumental changes in the way we now do business on the web and in the cloud. This article, the fourth in a four-part series designed to spotlight changes in HTML5, introduces the HTML5 Canvas element, using several examples to demonstrate functions.

Grace Walker, IT Consultant, Walker Automated Services

Grace Walker, a partner in Walker Automated Services in Chicago, Illinois, is an IT consultant with a diverse background and broad experience. She has worked in IT as a manager, administrator, programmer, instructor, business analyst, technical analyst, systems analyst, and Web developer in various environments, including telecommunications, education, financial services, and software.



05 July 2011

Also available in Chinese Russian Japanese Vietnamese

The role of the HTML5 author, an intrepid combination of designer and developer, is to construct effective rich Internet applications (RIA) and especially rich UIs. By effective, I mean the creation of systemic and systematic enhancements that digitally facilitate the dialog among the site owner, agents of the owner, and the site's users.

Develop skills on this topic

This content is part of a progressive knowledge path for advancing your skills. See HTML5 fundamentals

RIAs are the source and vehicle of a satisfying user experience and, therefore, are an essential part of any successful net-centric venture. Net-centric activities, by nature, are collaborative to one degree or another. A winning approach to digital collaboration is essential for agency success at all levels, including marketing and management. A lot rides on the efficiency with which the site satisfies the quality expectations of its visitors.

HTML5, as you have seen, is tailor-made for the collaborative "one web world" of cross-platform capabilities, converging telecommunications, unified language, ubiquitous computing, and open systems. The first three installments of this series focused on semantics, the proper coding methods, the role that input plays in the vital conversion process, and best practices of site management, all of which was designed to lay the foundation for the creation of RIAs in an organized and logical manner. The common thread in each article has been that the production and management of a rich user experience is critical to achieving the agency objectives of the owners of the website. The HTML5 Canvas has a critical role to play in the development of effective RIAs.

Frequently used acronyms

  • 2D: Two-dimensional
  • Ajax: Asynchronous JavaScript + XML
  • API: Application programming interface
  • HTML: Hypertext Markup Language
  • HTML5: HTML version 5
  • UI: User interface

What is the Canvas?

The HTML5 Canvas is an extremely useful drawing and animation element. Canvas uses JavaScript to draw graphics directly on the page. It is a rectangular area that you define and control and that permits dynamic, scriptable rendering of 2D shapes and bitmap images.

The HTML5 Canvas is perfect for producing great visual material that enhances UIs, diagrams, photo albums, charts, graphs, animations, and embedded drawing applications. The Canvas element has several methods for drawing paths, rectangles, circles, and characters.


Canvas coordinates

A prerequisite to drawing on the canvas is familiarity with the grid or coordinate space. The spatial area measurements for the width and height are given in pixels. The canvas is built around the use of the x and y coordinates. The canvas coordinates at x=0, y=0 are in the upper-left corner.

The default attributes for the canvas rectangle area is 300 pixels wide and 150 pixels high, but you can determine the exact size of the canvas element by specifying width and height. The diagram in Figure 1 shows how the x and y coordinates are implemented.

Figure 1. Canvas coordinates
Square with diagonal and horizontal lines through it showing the coordinates at each intersection.

Figure 1 shows a canvas area that is 100 pixels by 100 pixels:

  • The top left corner is x=0, y=0.
  • The x value increases horizontally, and the y value increases vertically.
  • The bottom right corner is x=100, y=100.
  • The center point is x=50, y=50.

Getting started

To put anything on the canvas, you must first define the canvas in the HTML file. You must create JavaScript code that accesses the <canvas> tag and communicates with the HTML5 Canvas API to draw your image.

The basic structure of the <canvas> tag is:

<canvas id="myCanvas" width="200" height="200"></canvas>

A canvas element has two attributes of its own: width and height. In addition, Canvas possesses all the key HTML5 attributes, such as class, id, and name. The id attribute is used in the code shown above. JavaScript uses the canvas id created here to identify the canvas to paint on. JavaScript determines the appropriate canvas using the document.getElementById() method, as shown here:

var canvas = document.getElementById("myCanvas");

Every canvas must have a context definition, as shown below. Currently, the official specification recognizes only a 2D environment:

var context = canvas.getContext("2d");

After you identify the canvas and specify its context, you're ready to begin drawing.


Drawing tools, effects, and transformations

This discussion of the HTML5 Canvas goes over various drawing tools, effects, and transformations. The drawing tools include:

  • Lines
  • Rectangles
  • Arcs
  • Bezier and quadratic curves
  • Circles and semicircles

The Canvas effects you will use are:

  • Fills and strokes
  • Linear and radial gradients

The transformations discussed include:

  • Scaling
  • Rotation
  • Translation

Drawing lines

To draw a line on the canvas, use the moveTo(), lineTo(), and stroke() methods. In addition, you use the beginPath() method to reset the current path:

  • context.beginPath();
  • Context.moveTo(x,y);
  • Context.lineTo(x,y);
  • Context.stroke(x,y);

The beginPath() method starts a new path. Before you draw a new line with different sub-paths, you must use beginPath() to indicate that a new starting point for a drawing is to follow. The beginPath() method does not have to be called when you draw the first line.

The moveTo() method states where the new sub-path is to start. The lineTo() method creates sub-paths. You can change the appearance of the line with lineWidth and strokeStyle. The lineWidth element changes the thickness of the line, and strokeStyle changes the color.

In Figure 2, three lines are drawn in blue, green, and purple, respectively.

Figure 2. Canvas with lines in three different colors
A canvas showing three lines in different colors

The lines in Figure 2 were created by the code in Listing 1. The blue line with round ends is created by first establishing that a new path is to begin: context.beginPath(). It is followed by:

  • context.moveTo(50, 50), which places the starting point for the path at (x=50, y-50)
  • context.lineTo(300,50), which identifies the end point for the line
  • context.lineWidth = 10, which is the width of the line
  • context.strokeStyle = "#0000FF", which is the color of the line
  • context.lineCap = "round", which makes the ends round
  • context.stroke(), which actually paints the line on the canvas

All the lines are 50 pixels in length, though they appear to be different lengths—a visual illusion caused by the line caps. There are three possible line caps:

  • Context.round (blue)
  • Context.square (green)
  • Context.butt (purple—the default)

The butt cap is the default value. When you use a round or square cap style the length of the line increases by an amount equal to the width of the line. For example, a line that is 200 pixels long and 10 pixels wide with a round or square cap style will have a resulting line length of 210 pixels, because each cap will add 5 pixels to each end of the line. A line that is 200 pixels long and 20 pixels wide with a round or square cap style will have a resulting line length of 220 pixels, because each cap will add 10 pixels to each end of the line.

Execute and alter the code in Listing 1 to gain a greater understanding of how lines are drawn.

Listing 1. Create three lines of different colors on the canvas
<!DOCTYPE HTML>
<html>
    <head>
	    <title>Line Example</title>
        <style>
            body {
                margin: 0px;
                padding: 0px;
            }
            
            #myCanvas {
                border: 1px solid #9C9898;
            }
        </style>
        <script>
            
          window.onload = function() {
                var canvas = document.getElementById("myCanvas");
                var context = canvas.getContext("2d");
                
                // blue line with round ends
                context.beginPath();
                context.moveTo(50, 50);
                context.lineTo(300,50);
                context.lineWidth = 10;
                context.strokeStyle = "#0000FF"; 
                context.lineCap = "round";
                context.stroke();

                // green line with square ends
                context.beginPath();
                context.moveTo(50, 100);
                context.lineTo(300,100);
                context.lineWidth = 20;
                context.strokeStyle = "#00FF00"; 
                context.lineCap = "square";
                context.stroke();

                // purple line with butt ends
                context.beginPath();
                context.moveTo(50, 150);
                context.lineTo(300, 150);
                context.lineWidth = 30;
                context.strokeStyle = "#FF00FF"; 
                context.lineCap = "butt";
                context.stroke();
            };
        </script>
    </head>
    <body>
        <canvas id="myCanvas" width="400" height="200">
        </canvas>

    </body>
</html>

Drawing rectangles

There are three methods for addressing a rectangular area on the canvas:

  • fillRect(x,y,width,height), which draws a filled rectangle
  • strokeRect(x,y,width,height), which draws a rectangular outline
  • clearRect(x,y,width,height), which clears the given area and makes it fully transparent

For each of the three methods, x and y indicate the position on the canvas relative to the top-left corner of the rectangle (x=0, y=0), and width and height are the width and height of the rectangle, respectively.

Figure 3 shows the three rectangular areas created by the code in Listing 2.

Figure 3. Rectangle canvas
Yellow-filled box with a thick black square rectangle and a thin rectangle in it

The fillRect() method creates a rectangle filled in with the default fill color of black. The clearRect() method clears a rectangular area in the center of the first rectangle. It is in the center of the rectangle formed by the fillRect() method. The strokeRect creates a rectangle that has only a visible black border.

Listing 2. Rectangle canvas code
<!DOCTYPE HTML>
<html>
<head>
<title>Rectangle Example</title>
        <style>
            body {
                margin: 0px;
                padding: 0px;
            }
            
            #myCanvas {
                border: 1px solid #000000;
                background-color: #ffff00;
            }
        </style>
<script type="text/javascript">
function drawShape(){
   var canvas = document.getElementById('myCanvas');

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


    context.fillRect(25,25,50,50);
    context.clearRect(35,35,30,30);
    context.strokeRect(100,100,50,50);

}
</script>
</head>
<body onload="drawShape();">
   <canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>

Drawing arcs, curves, circles, and semicircles

Both the circle and semicircle use the arc() method. The arc() method takes six arguments:

context.arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);

The centerX and centerY arguments are the coordinates of the circle's center. The radius is the same as the mathematical equivalent: a straight line from the center to the circumference. The arc created will be part of the defined circle. The startAngle and endAngle arguments are the starting and ending points of the arc, respectively, in radians. The anticlockwise argument is a Boolean value. When the value is true the arc is drawn counterclockwise; when it is false the arc is drawn in the clockwise direction.

To draw a circle using the arc() method, define the starting angle as 0 and the ending angle as 2*PI, as shown here:

context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

To draw a semicircle using the arc() method, define the ending angle as startingAngle + PI, as shown here:

context.arc(centerX, centerY, radius, startingAngle, startingAngle + Math.PI, false);

Quadratic curve

You create a quadratic curve using the quadraticCurveTo() method shown below. Quadratic curves are defined by the context point, a control point, and an ending point. The control point determines the curvature of the line.

context.moveTo(x, y);
context.quadraticCurveTo(controlX, controlY, endX, endY);

Bezier curve

Just as with the quadratic curve, a Bezier curve has a start and end point; but unlike the quadratic curve, it has two control points:

context.moveTo(x, y);
context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);

You create a Bezier curve using the bezierCurveTo() method. Because the Bezier curve is defined with two control points rather than just one, you can create more complex curvatures.

Figure 4 shows—from left to right—an arc, a quadratic curve, a Bezier curve, a semicircle, and a circle.

Figure 4. Arc, curves, and circles
Image showing arcs, curves, circles, and semicircles on the canvas

Figure 4 was created using the code in Listing 3.

Listing 3. Arc, curve, and circle code
<!DOCTYPE HTML>
<html>
    <head>
	<title>Arcs, Curves, Circles, & Semicircles</title>
        <style>
            body {
                margin: 0px;
                padding: 0px;
            }
            
            #myCanvas {
                border: 1px solid #9C9898;
            }
        </style>
<script>
function drawArc(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    var centerX = 100;
    var centerY = 160;
    var radius = 75;
    var startingAngle = 1.1 * Math.PI;
    var endingAngle = 1.9 * Math.PI;
    var counterclockwise = false;
 
    context.arc(centerX, centerY, radius, startingAngle, 
        endingAngle, counterclockwise);
 
    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawQuadratic(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    context.moveTo(200, 150);
 
    var controlX = 288;
    var controlY = 0;
    var endX = 388;
    var endY = 150;
 
    context.quadraticCurveTo(controlX, controlY, endX, endY);
    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawBezier(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    context.moveTo(350, 350);
 
    var controlX1 = 440;
    var controlY1 = 10;
    var controlX2 = 550;
    var controlY2 = 10;
    var endX = 500;
    var endY = 150;
 
    context.bezierCurveTo(controlX1, controlY1, controlX2, 
        controlY2, endX, endY);
 
    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawCircle(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    var centerX = 450;
    var centerY = 375;
    var radius = 70;
 
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
 
    context.fillStyle = "#800000";
    context.fill();
    context.lineWidth = 5;
    context.strokeStyle = "black";
    context.stroke();
};


function drawSemicircle(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    var centerX = 100;
    var centerY = 375;
    var radius = 70;
    var lineWidth = 5;
 
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, Math.PI, false);
    context.closePath();
 
    context.lineWidth = lineWidth;
    context.fillStyle = "#900000";
    context.fill();
    context.strokeStyle = "black";
    context.stroke();
};

window.onload = function (){
drawArc();
drawQuadratic(); 
drawBezier(); 
drawCircle(); 
drawSemicircle()
}
</script>
    </head>
    <body>
        <canvas id="myCanvas" width="600" height="500">
        </canvas>
    </body>
</html>

Transformations: translate, scale, and rotate

The translate(), scale(), and rotate() methods all modify the current matrix. The translate(x, y) method moves items on the canvas to a different point on the grid. In the translate(x,y) method, the (x,y) coordinates indicate the number of pixels the image should be moved in the x-direction and the number of pixels the image has to be moved in the y-direction.

If you draw an image at (15,25) with the drawImage() method, you can use the translate() method with arguments (20,30), which places the image at position (15+20, 25+30) = (35, 55).

The scale(x,y) method changes the size of an image. The x argument specifies a horizontal scaling factor, and the y argument specifies a vertical scaling factor. For example, scale(1.5, .75) would create an image that is 50% larger in the x-direction and only 75% of the current size in the y-direction. The rotate(angle) method turns an object based on the angle specified.

Figure 5 is an example of what can be rendered using the translate(), scale(), and rotate() methods.

Figure 5. Using transformations
Image showing a blue box with the words mirror image reading from the right.

Listing 4 provides the code that created the image in Figure 5.

Listing 4. Code to create transformations
<!DOCTYPE HTML>
<html>
<head>
<Title>Transformations Example</title>
<script>
 
window.onload = function() {
	var canvas=document.getElementById("myCanvas");
	var context=canvas.getContext("2d");
 
	var rectWidth = 250;
	var rectHeight = 75;
 
	// translate context to center of canvas
	context.translate(canvas.width/2,canvas.height/2); 		
 
	// half the y component 
	context.scale(1,0.5);

	// rotate 45 degrees clockwise
	context.rotate(-Math.PI/4); 
 
	context.fillStyle="blue";
	context.fillRect(-rectWidth/2,-rectHeight/2,
		rectWidth,rectHeight);


	// flip context horizontally
	context.scale(-1,1);
 
	context.font="30pt Calibri";
	context.textAlign="center";
	context.fillStyle="#ffffff";
	context.fillText("Mirror Image",3,10);

}
 
</script>
</head>
<body>
	<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

Gradients

A gradient is a fill that moves from one color to another, blending the colors where they intersect. There are two types of gradients that you can create in Canvas: linear and radial.

You create a linear gradient using the createLinearGradient() method. createLinearGradient(x0,y0,x1,y1) produces a gradient along a straight line identified by two points: (x0,y0) and (x1,y1)—the start and end points of the gradient, respectively. The method returns an object.

A color gradient can have many colors. The addcolorStop(offset, color) method specifies the color stop for the indicated color to the gradient at the given offset. The addColorStop() method lets you specify an offset between 0 and 1, where the transition to the next color begins. The value 0 is the offset at one end of the gradient; 1 is the offset at the other end. After the color gradient has been defined, the gradient object can be assigned to fillStyle(). You can also draw text with a gradient using the fillText() method.

A radial gradient—createradialGradient(x0,y0,r0,x1,y1,r1)—combines two or more colors in a circular or conical pattern using six arguments:

  • (x0,y0). The center of the first circle of the cone
  • r0. The radius of the first circle
  • (x1,y1). The center of the second circle of the cone
  • r1. The radius of the second circle

Figure 6 contains four gradients: a linear gradient, a text gradient, a linear gradient on a diagonal, and a radial gradient.

Figure 6. Gradient example
Drawing gradients on the canvas

Figure 6 was created using the code in Listing 5.

Listing 5. Gradient example code
<!doctype>
<html>
<head>
<title>Gradient Example</title>
<script>
   window.onload = function() {
      var canvas = document.getElementById("myCanvas");

      var context = canvas.getContext("2d");

      //Let's try the gradient on a rectangle

      // Create a linear gradient 
      var fillColor = context.createLinearGradient(50,50, 150,50);

      // Set  gradient colors
      fillColor.addColorStop(0.15,"red");
      fillColor.addColorStop(0.35,"black");
      fillColor.addColorStop(0.65,"green");
      fillColor.addColorStop(0.87,"yellow");

      // Assign gradient object to fillstyle
      context.fillStyle= fillColor;

      // Draw rectangle
      context.fillRect(50,50,100,100);

      // With text  

      var fillColorText = context.createLinearGradient(300,50,600,50);
 
      fillColorText.addColorStop(0.2,"red");
      fillColorText.addColorStop(0.4,"black");
      fillColorText.addColorStop(0.6,"green");
      fillColorText.addColorStop(0.8,"yellow");


     context.fillStyle= fillColorText;

      context.font="40px verdana";
      context.textBaseline="top";
      context.fillText("With text too!", 300,50)

      // Gradient on a diagonal
      var fillColordiagonal = context.createLinearGradient(50,200, 100,450);

      // Gradient colors
      fillColordiagonal.addColorStop(0.2,"red");
      fillColordiagonal.addColorStop(0.4,"black");
      fillColordiagonal.addColorStop(0.6,"green");
      fillColordiagonal.addColorStop(0.75,"yellow");

      // Assign gradient object to fillstyle
      context.fillStyle= fillColordiagonal;

      // Draw  rectangle
      context.fillRect(50,225, 100,250);

      // Draw radial gradient
     fillColorRadial = context.createRadialGradient(450,300,0, 450,300,200);
     fillColorRadial.addColorStop(0, "red");
     fillColorRadial.addColorStop(0.2, "black");
     fillColorRadial.addColorStop(0.4, "green");
     fillColorRadial.addColorStop(0.7, "yellow");
     context.fillStyle = fillColorRadial;
     context.rect(300,200,500,400);
     context.fill();

}
</script>
</head>
<body>
<div>
    <p><canvas id="myCanvas" width="600" height="400"></canvas></p>
</div>
</body>
</html>

Image cropping

You can alter images by cropping selected areas out of them. Cropping on the canvas is a function of overloading the drawImage() method. The drawImage() method has three options. You can use either three, five, or nine arguments.

The three-argument configuration—drawImage(image, dx, dy)—draws the image on the canvas at the destination coordinates (dx, dy). The coordinates form the upper-left corner of the image.

The-five argument configuration—drawImage(image, dx, dy, dw, dh)—provides a width and height for the destination. The image is scaled to fit the destination width and height.

The nine-argument configuration—drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)—takes an image, clips out a rectangular area that starts at the source (sx,sy) coordinates with a width and height of (sw,sh), and scales it to fit the destination width and height (dw,dh), placing it on the canvas at (dx,dy).

Figure 7 shows the image that you'll crop.

Figure 7. Cropping an image
A portrait of Napoleon riding a horse.

Using the image shown in Figure 7, a set of images is placed on the canvas. One image is canvas-sized and used as the background. Another image is created that is smaller and inserted at the bottom right of the canvas. A third image is a cut-out of Napoleon's head that you place in the upper-left corner of the canvas. The final cropped image is shown in Figure 8.

Figure 8. The final cropped image
Same Napoleon image but with a headshot in the upper left and a smaller image in the bottom right

Figure 8 was created using the code in Listing 6. Before executing this code, be sure to download the Napolean.png image used in the example.

Listing 6. Code to crop the example image
<!doctype>
<html>
<head>
<title>Crop Example</title>
<script type="text/javascript">
  window.onload = function()  {
  var canvas=document.getElementById("cropNapolean");
	var context=canvas.getContext("2d");
 
	var imageObj = new Image();
	imageObj.onload = function() {
	// draw image to cover the entire canvas
		context.drawImage(imageObj,0,0, 600, 400);
 
	// draw small image in bottom right corner
		var sourceX = 0;
		var sourceY = 0;
		var sourceWidth = 1200;
		var sourceHeight = 801;
		var destX = 300;
		var destY = 200;
		var destWidth = sourceWidth - 900;
		var destHeight = sourceHeight - 600;
 
		context.drawImage(imageObj, sourceX, sourceY, sourceWidth,
			sourceHeight, destX, destY, destWidth, destHeight);
	
	 //draw Napolean's head only
		var sourceNapoleanX = 460;
		var sourceNapoleanY = 25;
		var sourceNapoleanWidth = 250;
		var sourceNapoleanHeight = 175;
		var destNapoleanX = 0;
		var destNapoleanY = 0;
		var destNapoleanWidth = sourceNapoleanWidth - 150 ;
		var destNapoleanHeight = sourceNapoleanHeight - 100;
 
        context.drawImage(imageObj, sourceNapoleanX, sourceNapoleanY, 
             sourceNapoleanWidth, sourceNapoleanHeight, 
               destNapoleanX, destNapoleanY, 
                 destNapoleanWidth, destNapoleanHeight);
	}
	imageObj.src = "Napoleon.png";	
}
</script>
  
  </head>
<body>
  <div>
    <p><canvas id="cropNapolean" width="600" height="400"></canvas></p>
  </div>
</body>
</html>

Animation and multiple canvases

When working with animation, the question of layers always arises. Layers allow components to be isolated, which makes coding and debugging easier and more efficient. The Canvas API doesn't have layers, but you can create multiple canvases.

Animation must be controlled over time. So, to create an animation, you must address each frame of the animation. The Canvas API has one major limitation when it comes to animation: After a shape is drown on the canvas, it stays that way. To move the shape, you must redraw it.

To create an animation:

  1. Clear the canvas of any shapes that have been drawn previously.
  2. Save the canvas state to make sure the original state is used each time a frame is drawn.
  3. Perform the steps to render the frames.
  4. If you have saved the state, restore it before drawing a new frame.

You can control animation in two ways: by using the setInterval or setTimeout functions, each of which can be used to call a function over a set time period. The setInterval function executes the provided code repeatedly. The setTimeout function executes only once after the time provided has elapsed.

Figure 9 shows one frame of the multiple-canvas animation of the swimmer. The water is on one canvas, and the swimmer is on another.

Figure 9. Animation using images on multiple canvases
Stick figure on a blue gradient background.

You create the swimmer using the code in Listing 7. The swimmer uses a linear gradient to create the water. The water has four shades of blue, which provides a reasonable illusion of water. You create the swimmer's motion using the positionX and positionY values, which alter the poses of the image. You create the swimmer's head using the arc() method. The legs and arms of the swimmer are created by drawing lines and then changing their lineTo() positions. You change the torso by altering the moveTo() position. Because this is an animation, you will have to execute this code to see how the swimmer moves.

Listing 7. Animation example
<!DOCTYPE HTML>
<html>
    <head>
	<title>Animation & Multiple Canvas Example</title>
<script>            
// Water canvas
function  drawWater() {
    var canvasWater = document.getElementById("myWaterCanvas");
    var contextWater = canvasWater.getContext("2d");
	contextWater.globalAlpha = .50 ;

    // Create a linear gradient fill
    var linearGrad = contextWater.createLinearGradient(0,0,400,400);
    linearGrad.addColorStop(0, '#0000ff'); // sets the first color
    linearGrad.addColorStop(.25, '#0099ff'); // sets the second color
    linearGrad.addColorStop(.50, '#00ccff'); // sets the third color
    linearGrad.addColorStop(.75, '#00ffff'); // sets the fourth color
    contextWater.fillStyle = linearGrad;
    contextWater.fillRect(0,0,400,400);
}

// Swimmer canvas
           setInterval(drawSwimmer, 30);
           var positionX = 0;
           var positionY = 0;
            
          function  drawSwimmer(){
                var canvasSwimmer = document.getElementById("mySwimmerCanvas");
                var contextSwimmer = canvasSwimmer.getContext("2d");
                contextSwimmer.clearRect(0,0,400,400);

                if (positionX < 30)
                  {
                     positionX += 1;
                     positionY += 1;
                  }
                else
                {
                     positionX = 0;
                     positionY = 0;
                }
               

                contextSwimmer.save();

               // draw circle for head
               var centerX = 200;
               var centerY = 50;
               var radius = 20;
 
               contextSwimmer.beginPath();
               contextSwimmer.arc(centerX, centerY+positionY, 
			                         radius, 0, 2 * Math.PI, false);
 
               contextSwimmer.fillStyle = "#000000";
               contextSwimmer.fill();
               contextSwimmer.lineWidth = 5;


                // torso
                contextSwimmer.beginPath();
                contextSwimmer.moveTo(200,70+positionY);
                contextSwimmer.lineTo(200,175);
                contextSwimmer.lineWidth = 10;
                contextSwimmer.strokeStyle = "#000000"; 
                contextSwimmer.lineCap = "round";
                contextSwimmer.stroke();

               // image right arm
                contextSwimmer.beginPath();
                contextSwimmer.moveTo(200, 100);
                contextSwimmer.lineTo(175-positionX,140-positionY);
                contextSwimmer.lineWidth = 10;
                contextSwimmer.strokeStyle = "#000000"; 
                contextSwimmer.lineCap = "round";
                contextSwimmer.stroke();

               // image left arm
                contextSwimmer.beginPath();
                contextSwimmer.moveTo(200, 100);
                contextSwimmer.lineTo(225+positionX,140-positionY);
                contextSwimmer.lineWidth = 10;
                contextSwimmer.strokeStyle = "#000000"; 
                contextSwimmer.lineCap = "round";
                contextSwimmer.stroke();

               // image right leg
                contextSwimmer.beginPath();
                contextSwimmer.moveTo(200, 175);
                contextSwimmer.lineTo(190-positionX,250-positionY);
                contextSwimmer.lineWidth = 10;
                contextSwimmer.strokeStyle = "#000000"; 
                contextSwimmer.lineCap = "round";
                contextSwimmer.stroke();


               // image left leg
                contextSwimmer.beginPath();
                contextSwimmer.moveTo(200, 175);
                contextSwimmer.lineTo(210+positionX,250-positionY);
                contextSwimmer.lineWidth = 10;
                contextSwimmer.strokeStyle = "#000000"; 
                contextSwimmer.lineCap = "round";
                contextSwimmer.stroke();

                contextSwimmer.restore();

           };

</script>

</head>
    <body onload="drawWater();">
        <canvas id="myWaterCanvas" width="400" height="400" style="z-index: 2; 
		              position:absolute;left:0px;top:0px;">
        </canvas>
        <canvas id="mySwimmerCanvas" width="400" height="400" style="z-index: 1; 
		              position:absolute;left:0px;top:0px;">
        </canvas>

    </body>
</html>

Conclusion

The HTML5 canvas is central to the construction of browser-based RIAs. It provides a utilitarian drawing environment powered by JavaScript and your imagination. It is not really difficult to learn, and there are many support tools on the web for your training and learning needs, including cheat sheets, blogs, online articles, video and non-video tutorials, and sample applications.

The ability to alter text and images visually and to simulate motion makes Canvas an extremely valuable tool. Whether you approach it from the perspective of a designer or developer, use Canvas to build game applications to run on mobile devices, or merely want to enhance the use of the overall screen real estate, Canvas is a critical component of the HTML5 experience.


Download

DescriptionNameSize
Napoleon imageNapoleon.zip2045KB

Resources

Learn

Get products and technologies

  • The Dojo Toolkit, an open source modular JavaScript library, helps you quickly develop cross-platform, JavaScript/Ajax-based applications and websites.
  • Try out IBM software for free. Download a trial version, log into an online trial, work with a product in a sandbox environment, or access it through the cloud. Choose from over 100 IBM product trials.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development
ArticleID=697327
ArticleTitle=HTML5 fundamentals, Part 4: The final touch
publish-date=07052011