Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw grid using HTML5 and canvas or SVG

I want to draw a grid as shown in the image but I totally don't have any idea where to begin.

Should I use SVG or should I use Canvas with HTML5 and how do I draw on it?

I want this grid to draw rectangle, circle or other diagrams on it and I will calculate the area of that diagram like area of a square.

grid

like image 266
Sandeep Kumar Avatar asked Jan 08 '13 05:01

Sandeep Kumar


People also ask

Should I use canvas or SVG?

SVG gives better performance with smaller number of objects or larger surface. Canvas gives better performance with smaller surface or larger number of objects. SVG is vector based and composed of shapes. Canvas is raster based and composed of pixel.

What is the difference between SVG and HTML5 canvas?

Difference between SVG and HTML5 Canvas: Canvas has poor scalability. Hence it is not suitable for printing on higher resolution. SVG gives better performance with smaller number of objects or larger surface. Canvas gives better performance with smaller surface or larger number of objects.


2 Answers

SVG can do this nicely using patterns:

<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">   <defs>     <pattern id="smallGrid" width="8" height="8" patternUnits="userSpaceOnUse">       <path d="M 8 0 L 0 0 0 8" fill="none" stroke="gray" stroke-width="0.5"/>     </pattern>     <pattern id="grid" width="80" height="80" patternUnits="userSpaceOnUse">       <rect width="80" height="80" fill="url(#smallGrid)"/>       <path d="M 80 0 L 0 0 0 80" fill="none" stroke="gray" stroke-width="1"/>     </pattern>   </defs>          <rect width="100%" height="100%" fill="url(#grid)" /> </svg>

I set width and height to 100%, so you can define the actual width and height on use, either for inline SVG:

<div style="width:400px;height:300px">   <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">     <defs>       <pattern id="smallGrid" width="8" height="8" patternUnits="userSpaceOnUse">         <path d="M 8 0 L 0 0 0 8" fill="none" stroke="gray" stroke-width="0.5"/>       </pattern>       <pattern id="grid" width="80" height="80" patternUnits="userSpaceOnUse">         <rect width="80" height="80" fill="url(#smallGrid)"/>         <path d="M 80 0 L 0 0 0 80" fill="none" stroke="gray" stroke-width="1"/>       </pattern>     </defs>              <rect width="100%" height="100%" fill="url(#grid)" />   </svg> </div>

or an <img> element:

<img src="https://svgshare.com/i/eGa.svg" width="700" height="200"/> 

results in:

<img src="https://svgshare.com/i/eGa.svg" width="241" height="401"/> 

results in

Note that for this particular grid you have to use widths and heights of the form n x 80 + 1 (with n being any integer) if you want the grid to start and end with a thick stroke.

like image 52
Thomas W Avatar answered Sep 18 '22 15:09

Thomas W


I am posting my code using canvas here on SO but I am also creating a working sample on JSFiddle here.

<!DOCTYPE html> <html> <head>     <title>StackOverflow test bed</title>     <script type="text/javascript">         function drawGrid() {             var cnv = document.getElementById("cnv");              var gridOptions = {                 minorLines: {                     separation: 5,                     color: '#00FF00'                 },                 majorLines: {                     separation: 30,                     color: '#FF0000'                 }             };              drawGridLines(cnv, gridOptions.minorLines);             drawGridLines(cnv, gridOptions.majorLines);              return;         }          function drawGridLines(cnv, lineOptions) {               var iWidth = cnv.width;             var iHeight = cnv.height;              var ctx = cnv.getContext('2d');              ctx.strokeStyle = lineOptions.color;             ctx.strokeWidth = 1;              ctx.beginPath();              var iCount = null;             var i = null;             var x = null;             var y = null;              iCount = Math.floor(iWidth / lineOptions.separation);              for (i = 1; i <= iCount; i++) {                 x = (i * lineOptions.separation);                 ctx.moveTo(x, 0);                 ctx.lineTo(x, iHeight);                 ctx.stroke();             }               iCount = Math.floor(iHeight / lineOptions.separation);              for (i = 1; i <= iCount; i++) {                 y = (i * lineOptions.separation);                 ctx.moveTo(0, y);                 ctx.lineTo(iWidth, y);                 ctx.stroke();             }              ctx.closePath();              return;         }      </script> </head> <body onload="drawGrid()">     <canvas id="cnv" width="500" height="500"></canvas> </body> </html> 

Using the canvas approach you can make the grid size dynamic by changing the separation parameter.

However, if your grid size is going to be static I feel that maybe you don't need to draw the grid. Just for the sake of displaying a grid to the user you could use CSS to repeat a background image as demonstrated in the fiddle here. That will also be good on page performance.

like image 20
Tanzeel Kazi Avatar answered Sep 17 '22 15:09

Tanzeel Kazi