Drawing Playground Using HTML 5 Canvas And JavaScript

Overview
 
In this article, I am going to draw a graphics for football playground using HTML5 Canvas element & JavaScript. Visually, canvas is nothing more than an HTML element but it is more powerful to draw any kind of graphics on it.
 
Basically, it is a container for graphics design on which one can draw graphics with the help of JavaScript. Similar to other HTML elements, we can set the properties like height, width, id, styles, and other attributes. We can understand this in the following image where I have mentioned the id of canvas as "canvasPlayground".
 
CanvasElement 
Figure: canvas
 
Story  
 
Yes, it's true. I had very less knowledge of football playground like what is penalty area, penalty spot, goal area, and so many things. So two days ago, I was studying about football playground meanwhile I saw a magnificent image of playground then there is question came into my mind - "Can I draw the same type of ground image using programming?" and I got an answer, Yes I can do.
 
There can be a different way to draw this image but for this article/solution I am using HTML5 canvas with JavaScript. 
 
 

Note

In this article, I am going to draw the same football ground with different color
 
Before Start
 
Before going to start drawing for football ground, lets know about the basics concept of canvas and it's methods which are being used to draw the objects on it. The <canvas> element creates a fixed size of drawing surface which either may be in 2d context or 3. But in this article, I am going to discuss about the 2 context only.
 
We can draw the various kind of shapes and text but in this article I will use the following only. May be in the next article I will explore more about canvas.
  • Circle
    To draw circular shape over the canvas, in this article I will use circle object to draw center spot and penalty arc

  • Rectangle
    we can draw rectangular share where need to show rectangular object. In this article I will use it draw sevral shape like     penalty area, goal area, main ground.

  • Line
    we can draw line on canvas by using line. I will use it draw draw half-way line of the ground as well as arrow line to inicate the name of the ground area.

  • Text
    We can draw text as well. So In this article I will use it to indicate the information of ground.
The <canvas> element has a method called getContext(), which is used to rendering context and its drawing functions. getContext() takes one parameter as type of context that may be either 2D or 3D.

Example
  1. var canvasElement = document.getElementById("canvasPlayground");    
  2. var context = canvasPlayground.getContext("2d");    
All latest browser have the support for canvas. I think IE8 doesn't support canvas. So by the following line of code we can check that is this browser have support of canvas or not. 
  1. //Check is this browser has support for canvas or not  
  2. if(canvasElement.getContext){  
  3.      //This browser has support for canvas  
  4. }  
  5. else{  
  6.      //it doesn't have support for canvas  
  7. }  
Some of us(beginners) may not be aware about the canvas so let's look a brief about some basic functions which will be used in this article.
 
List of canvas functions which are will be used in this article: 
  • beginPath()
    It is used to create a new path after that we can move the path by using moveTo(), lineTo() or any other function.
    1. //...  
    2. context.beginPath();  
    3. //...  

  • moveTo(xPostion, yPosition)
    It is used to moves the pen to the  specified coordinates. Basically, we use this function for starting point but we can use it where we need to change the direction of path as well.
    1. context.moveTo(0,0);  
  • lineTo(xPostion, yPosition)
    It's used to draw straight line. This method takes two arguments, xPostion and yPosition, which are the coordinates of the line's end point
    1. //...  
    2. context.lineTo(0,0);  
    3. context.lineTo(100,0)  
    4.   
    5. //..  
  • fill()
    It's used to draw the solid path by filling the path area

  • fillStyle()
    It's used to fill the background color

  • stroke()
    It's used to draw shape with outline/border

  • strokeStyle()
    It's used to fill the color of stroke outline

  • lineWidth()
    It's used to change the width of stroke line

  • arc(xPos, yPos, radius, startAngle, endAngle, anticlockwise)
    To draw arcs or circles, we use the arc() or arcTo() methods.

  • fillRect(xPos, yPos, width, height)
    It is used to draw  fill rectangualr shape from the specified x an y postion with mentioned  dimention(with x height)

  • strokeRect(x, y, width, height)
    It is used to draw fill rectangel outline

  • clearRect(x, y, width, height)
    It is use to clears the specified rectangular area by making it fully transparent.
Let us start step by step to draw football playground on canvas
 
For this article I am using Visual Studio 2013 but it's not mandatory. We can do it by using Notepad with any browsers.
 
Step1
 
Create an index.html page and replace the existing code by following lines of code
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.     <title></title>  
  5. </head>  
  6. <body style="margin:0 auto; background:#333; ">  
  7.     <div id="DrawingBoard" style="padding-top:25px;text-align:center ">  
  8.         <canvas id="canvasPlayground" ></canvas>  
  9.     </div>  
  10.       
  11.     <script src="JavaScript/canvas-painting.js"></script>  
  12. </body>  
  13. </html>  
Step2

Create a new javascript file and named it as canvas-painting.js or named to according to your choice and update the script reference
 
Step3

To make the calculation feasible and centralized I have declared some variables which will be used using drawing the playground. So pase the following code snippet into your javascript file.
  1. var _height=500;//height of the canvas  
  2. var _width = 1000; //width of the canvas  
  3. var x1 = 0, y1 = 0, x2; y2 = 0;  
  4.   
  5. var canvas = {  
  6.     width: _width,  
  7.     height: _height,  
  8.     halfWidth: _width / 2,  
  9.     lineWith: 2,  
  10.     backgorund: { Default: "#08a107", Orange: "#f60", Green: "#f80" },  
  11.     borerColor: { White: "#fff", Green: "#f80" },  
  12.     colorMap: { Orange: "#f60", Green: "#f80" }  
  13. };  
  14. var common = {  
  15.     fillColor: { Default: "#0d5f0c", Green: "green", Red: "red", Orange: "#f60", White: "#fff" },  
  16.     borderColor: "#fff",  
  17.     fontFamily: " 'Segoe UI',Arial,sans-serif",  
  18.     font: { Default: "12px 'Segoe UI',Arial,sans-serif", Heading: "14px 'Segoe UI',Arial,sans-serif" },  
  19.     lineWidth: { Pixel1: 1, Pixel2: 2, Pixel3:3, Pixel4: 4, Pixel5: 5 },  
  20.     arrowLength:{Default:70,Pixel50:50}  
  21. };  
  22.   
  23. var penaltyArea = {  
  24.     height: Math.ceil((canvas.height * 70) / 100),  
  25.     width: Math.ceil((canvas.width * 12) / 100),  
  26.     yPosition: Math.ceil(((canvas.height * 30) / 100) / 2),  
  27.     xPosition: { TeamA: 0, TeamB: canvas.width - Math.ceil((canvas.width * 12) / 100) }  
  28. };  
  29. var goalArea = {  
  30.     height: Math.ceil((penaltyArea.height * 60)/100),  
  31.     width: Math.ceil(penaltyArea.width / 2),  
  32.     yPositon: (canvas.height - penaltyArea.height),  
  33.     xPosition: { TeamA: 0, TeamB: Math.ceil(canvas.width - (penaltyArea.width / 2)) }  
  34. };  
  35. var penaltyArc = {  
  36.     xPosition: { TeamA: penaltyArea.width - goalArea.width / 4, TeamB: canvas.width - penaltyArea.width + goalArea.width / 4 },  
  37.     yPosition: canvas.height/2,  
  38.     radius:goalArea.height/3  
  39. };  
  40.   
  41. var groundCorner={  
  42.     radius:Math.ceil((canvas.height*2)/100)  
  43. };  
Step4
 
Now add the following codesnippet in your javascript file because I will use these variable in upcoming functions
  1. var captioinText = "";  
  2. var canvasElement = document.getElementById("canvasPlayground");  
  3. var context = canvasPlayground.getContext("2d");  
Step5
 
Now I will create a function with name playgorund()  after that I will add some methods which will be used to draw playgorund. The name of the methods are bellow.
  • setGroundStyles() :   to set the height,width and background styles of canvas
  • drawCenterSpot():   to draw Center Spot of the ground at the center point of ground
  • drawCorner():   to draw arc on the all four courners
  • drawPenaltyArea():   to draw penalty arc for both team
  • drawGoalArea():   to draw goal area for the both team
  • drawPenaltyArc():    to draw penalty at both penalty area
  • drawPenaltySpot():   to draw penalty spot for both team
  • writeText():   to indicate area of the ground by name
  • drawLine():   to draw the line like ground devider (Half-Way Line)
  • drawArrowLine():   to draw arrow line at text
  • drawCaptionForTeamA(): 
  • drawCaptionForTeamB():  
  1. function playground() {  
  2.   
  3. }  
  4. playground.prototype.setGroundStyles = function () {  
  5.     canvasElement.setAttribute("width", canvas.width);  
  6.     canvasElement.setAttribute("height", canvas.height);  
  7.     canvasElement.style.border = "2px solid " + canvas.borerColor.White;  
  8.     canvasElement.style.margin = "auto 25px";  
  9.     canvasElement.style.background = canvas.backgorund.Default;  
  10. }  
  11. playground.prototype.drawCenterSpot = function (xAxis, yAxis, radius) {  
  12.     context.beginPath();  
  13.     context.arc(xAxis, yAxis, radius, 0, 2 * Math.PI);  
  14.     context.fillStyle = common.fillColor.Default;  
  15.     context.fill();  
  16.     context.lineWidth = common.lineWidth.Pixel2;  
  17.     context.strokeStyle = common.borderColor;  
  18.     context.stroke();  
  19. }  
  20.   
  21. playground.prototype.drawCorner = function (xAxis, yAxis) {  
  22.     context.beginPath();  
  23.     context.arc(xAxis, yAxis, groundCorner.radius, 0, 2 * Math.PI);  
  24.     context.fillStyle = common.fillColor.Default;  
  25.     context.fill();  
  26.     context.lineWidth = common.lineWidth.Pixel2;  
  27.     context.strokeStyle = common.borderColor;  
  28.     context.stroke();  
  29.       
  30. }  
  31. //Rectangular Area  
  32. playground.prototype.drawPenaltyArea = function (xAxis, yAxis) {  
  33.     context.beginPath();  
  34.     context.fillStyle = common.fillColor.Default;  
  35.     context.fill();  
  36.     context.fillRect(xAxis, yAxis, penaltyArea.width, penaltyArea.height);  
  37.     context.lineWidth = common.lineWidth.Pixel2;  
  38.     context.strokeStyle = common.borderColor;  
  39.     context.strokeRect(xAxis, yAxis, penaltyArea.width, penaltyArea.height);  
  40. }  
  41. playground.prototype.drawGoalArea = function (xAxis, yAxis) {  
  42.     context.beginPath();  
  43.     context.fillStyle = common.fillColor.Default;  
  44.     context.fill();  
  45.     context.fillRect(xAxis, yAxis, goalArea.width, goalArea.height);  
  46.     context.lineWidth = common.lineWidth.Pixel1;  
  47.     context.strokeStyle = common.borderColor;  
  48.     context.strokeRect(xAxis, yAxis, goalArea.width, goalArea.height);  
  49. }  
  50. playground.prototype.drawPenaltyArc = function (xAxis, yAxis, radius) {  
  51.     context.beginPath();  
  52.     context.arc(xAxis, yAxis, radius, 0, 2 * Math.PI);  
  53.     context.fillStyle = common.fillColor.Default;  
  54.     context.fill();  
  55.     context.lineWidth = common.lineWidth.Pixel2;  
  56.     context.strokeStyle = common.borderColor;  
  57.     context.stroke();  
  58.   
  59. }  
  60. playground.prototype.drawPenaltySpot = function (xAxis, yAxis, radius) {  
  61.     context.beginPath();  
  62.     context.arc(xAxis, yAxis, radius, 0, 2 * Math.PI);  
  63.     context.fillStyle = common.fillColor.Default;  
  64.     context.fill();  
  65.     context.lineWidth = common.lineWidth.Pixel3;  
  66.     context.strokeStyle = common.borderColor;  
  67.     context.stroke();  
  68. }  
  69.   
  70. playground.prototype.writeText = function (text, xAxis, yAxis, font,color) {  
  71.     font = (typeof font == 'undefined') ? common.font.Default : font;  
  72.     color = (arguments.length >= 5) ? color : common.fillColor.White;  
  73.     context.font = font;  
  74.     context.fillStyle = color;  
  75.     context.fillText(text, xAxis, yAxis);  
  76.   
  77. }  
  78. playground.prototype.drawLine = function (x1, y1, x2, y2) {  
  79.     context.beginPath();  
  80.     context.moveTo(x1, y1);  
  81.     context.lineTo(x2, y2);  
  82.     context.stroke();  
  83.     context.lineWidth = common.lineWidth;  
  84.     context.fillStyle = common.fillColor.White;  
  85.     context.fill();  
  86. }  
  87. playground.prototype.drawArrowLine = function (x1, y1, x2, y2, isReverseArrow) {  
  88.     context.beginPath();  
  89.     context.moveTo(x1, y1);  
  90.     context.lineTo(x2, y2);  
  91.     context.strokeStyle = common.fillColor.Orange;  
  92.     context.lineWidth = common.lineWidth.Pixel1;  
  93.     context.stroke();  
  94.   
  95.     var x2ofLine = x2;  
  96.     var y2OfLine = y2;  
  97.   
  98.     if (!isReverseArrow) {  
  99.         for (var i = 0; i <= 2; i++) {  
  100.             x1 = x2ofLine;  
  101.             y1 = ((i == 0) || (i == 2)) ? (y2OfLine - 4) : (y2OfLine + 4);  
  102.             x2 = (i == 2) ? (x2ofLine) : (x2ofLine + 4);  
  103.             y2 = (i == 2) ? (y2OfLine + 4) : y2OfLine;  
  104.   
  105.             context.beginPath();  
  106.             context.moveTo(x1, y1);  
  107.             context.lineTo(x2, y2);  
  108.             context.lineWidth = common.lineWidth.Pixel2;  
  109.             context.strokeStyle = common.fillColor.Orange  
  110.             context.stroke();  
  111.         }  
  112.     }  
  113.     else {  
  114.         for (var i = 0; i <= 2; i++) {  
  115.             x1 = x2ofLine;  
  116.             y1 = ((i == 0) || (i == 2)) ? (y2OfLine + 4) : (y2OfLine - 4);  
  117.             x2 = (i == 2) ? (x2ofLine) : (x2ofLine - 4);  
  118.             y2 = (i == 2) ? (y2OfLine - 4) : y2OfLine;  
  119.   
  120.             context.beginPath();  
  121.             context.moveTo(x1, y1);  
  122.             context.lineTo(x2, y2);  
  123.             context.lineWidth = 2;  
  124.             context.strokeStyle = common.fillColor.Orange;  
  125.             context.stroke();  
  126.         }  
  127.     }  
  128.   
  129. }  
  130.   
  131. playground.prototype.drawCaptionForTeamA = function (ground) {  
  132.     //Caption for Penalty Area  
  133.     x1 = penaltyArea.width - 20;  
  134.     y1 = canvas.height - penaltyArea.height;  
  135.     x2 = x1 + common.arrowLength.Default;  
  136.     y2 = y1;  
  137.     ground.drawArrowLine(x1, y1, x2, y2, false);  
  138.     captioinText = "Penalty Area";  
  139.     ground.writeText(captioinText, x2, y2 - 10, common.font.Heading);  
  140.   
  141.     //Caption for Goal Area  
  142.     x1 = goalArea.width - goalArea.width / 2;  
  143.     y1 = canvas.height - goalArea.height + 60;  
  144.     x2 = x1 + common.arrowLength.Pixel50;  
  145.     y2 = y1;  
  146.     ground.drawArrowLine(x1, y1, x2, y2, false);  
  147.     captioinText = "Goal Area";  
  148.     ground.writeText(captioinText, x2, y2 - 10, common.font.Heading);  
  149.   
  150.     //Caption for Penalty Arc  
  151.     x1 = penaltyArea.width + 20;  
  152.     y1 = canvas.height / 2;  
  153.     x2 = x1 + common.arrowLength.Default;  
  154.     y2 = y1;  
  155.     ground.drawArrowLine(x1, y1, x2, y2, false);  
  156.     captioinText = "Penalty Arc";  
  157.     ground.writeText(captioinText, x2, y2 - 10, common.font.Heading);  
  158.   
  159.     //Caption for Penalty Spot  
  160.     x1 = goalArea.width / 2;  
  161.     y1 = canvas.height / 2;  
  162.     x2 = x1 + common.arrowLength.Pixel50;  
  163.     y2 = y1;  
  164.     ground.drawArrowLine(x1, y1, x2, y2, false);  
  165.     captioinText = "Penalty Spot";  
  166.     ground.writeText(captioinText, x2, y2 - 10, common.font.Heading);  
  167. }  
  168.   
  169.   
  170. playground.prototype.drawCaptionForTeamB = function (ground) {  
  171.   
  172.     //Caption for Penalty Area  
  173.     x1 = canvas.width - penaltyArea.width + 20;  
  174.     y1 = canvas.height - penaltyArea.height ;  
  175.     x2 = x1 - common.arrowLength.Default;  
  176.     y2 = y1;  
  177.     ground.drawArrowLine(x1, y1, x2, y2, true );  
  178.     captioinText = "Penalty Area";  
  179.     ground.writeText(captioinText, x2 - 50, y2 - 10, common.font.Heading);  
  180.   
  181.     //Caption for Goal Area  
  182.     x1 = canvas.width - goalArea.width/2;  
  183.     y1 = canvas.height - goalArea.height + 60;  
  184.     x2 = x1 - common.arrowLength.Pixel50;  
  185.     y2 = y1;  
  186.     ground.drawArrowLine(x1, y1, x2, y2, true);  
  187.     captioinText = "Goal Area";  
  188.     ground.writeText(captioinText, x2-50, y2 - 10, common.font.Heading);  
  189.   
  190.     //Caption for Penalty Arc  
  191.     x1 = canvas.width -  penaltyArea.width -20;  
  192.     y1 = canvas.height / 2;  
  193.     x2 = x1 - common.arrowLength.Default;  
  194.     y2 = y1;  
  195.     ground.drawArrowLine(x1, y1, x2, y2, true);  
  196.     captioinText = "Penalty Arc";  
  197.     ground.writeText(captioinText, x2 -50, y2 - 10, common.font.Heading);  
  198.   
  199.     //Caption for Penalty Spot  
  200.     x1 = goalArea.width / 2;  
  201.     y1 = canvas.height / 2;  
  202.     x2 = x1 + common.arrowLength.Pixel50;  
  203.     y2 = y1;  
  204.     ground.drawArrowLine(x1, y1, x2, y2, true);  
  205.     captioinText = "Penalty Spot";  
  206.     ground.writeText(captioinText, x2, y2 - 10, common.font.Heading);  
  207. }  
Step6

No add the following codesnippet which will draw the football playground on window load()  
  1. window.onload = function () {  
  2.     var xPos = 0;  
  3.     var yPos = 0;  
  4.     var ground = new playground();  
  5.     ground.setGroundStyles();  
  6.     setTimeout(function () {  
  7.         //First draw all corners  
  8.         ground.drawCorner(5, 5);//Left Top  
  9.         ground.drawCorner(5, canvas.height - 5); //Bottom Left      
  10.         ground.drawCorner(canvas.width - 5, 5); //Top Right  
  11.         ground.drawCorner(canvas.width - 5, canvas.height - 5); //Bottom Right  
  12.   
  13.         //Now draw ground devider after 500 ms  
  14.         setTimeout(function () {  
  15.             //Half-way line  
  16.             ground.drawLine(canvas.width / 2, 0, canvas.width / 2, canvas.height);  
  17.             captioinText = "Half-Way Line";  
  18.             xPos = (canvas.width / 2) + common.arrowLength.Default;  
  19.             yPos = canvas.height / 6;  
  20.   
  21.             //Now draw center spot  
  22.             setTimeout(function(){  
  23.                 ground.drawArrowLine(canvas.halfWidth, yPos, xPos, yPos);  
  24.                 ground.writeText(captioinText, xPos + 10, yPos, common.font.Heading);  
  25.                 ground.drawCenterSpot(canvas.width / 2, canvas.height / 2, penaltyArc.radius);  
  26.                 ground.drawPenaltySpot(canvas.width / 2, canvas.height / 2, 2);  
  27.   
  28.                 //Draw Team a Penaly Areas  
  29.                 setTimeout(function () {  
  30.                     //Team-A  
  31.                     captioinText = "Team - A";  
  32.                     xPos = Math.ceil((canvas.width) / 4) - Math.ceil(captioinText.length / 2);  
  33.                     yPos = 20;  
  34.                     ground.writeText(captioinText, xPos, yPos, common.font.Heading, "Yellow");  
  35.                     ground.drawPenaltyArc(penaltyArc.xPosition.TeamA, penaltyArc.yPosition, penaltyArc.radius);  
  36.                     ground.drawPenaltyArea(penaltyArea.xPosition.TeamA, penaltyArea.yPosition);  
  37.                     ground.drawGoalArea(goalArea.xPosition.TeamA, goalArea.yPositon);  
  38.                     ground.drawPenaltySpot(goalArea.width / 2, canvas.height / 2, 2);  
  39.                     ground.drawCaptionForTeamA(ground);  
  40.   
  41.                     ////Draw Team a Penaly Areas  
  42.                     setTimeout(function () {  
  43.                         //Team*B  
  44.                         captioinText = "Team - B";  
  45.                         xPos = canvas.width - canvas.width / 3.5;  
  46.                         ground.writeText(captioinText, xPos, yPos, common.font.Heading, "Yellow");  
  47.                         ground.drawPenaltyArc(penaltyArc.xPosition.TeamB, penaltyArc.yPosition, penaltyArc.radius);  
  48.                         ground.drawPenaltyArea(penaltyArea.xPosition.TeamB, penaltyArea.yPosition);  
  49.                         ground.drawGoalArea(goalArea.xPosition.TeamB, goalArea.yPositon);  
  50.                         ground.drawPenaltySpot(canvas.width - (goalArea.width / 2), canvas.height / 2, 2);  
  51.                         ground.drawCaptionForTeamB(ground);  
  52.   
  53.                         setTimeout(function () {  
  54.                             //Draw Captions for Center Spot  
  55.                             ground.drawArrowLine(canvas.halfWidth, canvas.height / 2, canvas.halfWidth + penaltyArc.radius * 2, canvas.height / 2, false);  
  56.                             captioinText = "Center Spot";  
  57.                             xPos = canvas.halfWidth + penaltyArc.radius * 2;  
  58.                             yPos = (canvas.height / 2) - 10;  
  59.                             ground.writeText(captioinText, xPos, yPos, common.font.Heading, "yellow");  
  60.                         }, 500);  
  61.   
  62.                     }, 500);  
  63.   
  64.                 }, 1000);  
  65.              
  66.             },500);  
  67.   
  68.         }, 500);  
  69.   
  70.     }, 5000);  
  71.   
  72. }  
You can see that I have use setTimeout function to draw the object one after another. 
 
Output

Output
  
Summary

In this article, we learned about HTML5 canvas element to draw football playground using JavaScript. In upcoming article, I will explore the more about canvas including 3d context and animations.