Drawing lines

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // Vertical lines
  4. for (var x = 0.5; x < 500; x += 10) {
  5.     ctx.moveTo(x, 0);
  6.     ctx.lineTo(x, 375);
  7. }
  8. // Horizontal lines
  9. for (var y = 0.5; y < 375; y += 10) {
  10.     ctx.moveTo(0, y);
  11.     ctx.lineTo(500, y);
  12. }
  13.  
  14. // Draw in blue
  15. ctx.strokeStyle = “#0000FF”;
  16.  
  17. // Until the execution of the next line, nothing has been drawn!
  18. ctx.stroke();

In this example, the entire grid is drawn during the execution of the last line of code, with the single call to ctx.stroke().

ANOTHER EXAMPLE MIXING FILLED AND WIREFRAME SHAPES (AND IMMEDIATE AND PATH MODES)

Try this interactive example here: http://jsbin.com/zetupi/4/edit

two consecutive lines and a filled rectangle in immediate mode

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // a filled rectangle in immediate mode
  4. ctx.fillStyle=‘#FF0000’;
  5. ctx.fillRect(0,0,80,100);
  6. // two consecutive lines in path mode
  7. ctx.moveTo(0,0);
  8. ctx.lineTo(100, 100);
  9. ctx.lineTo(100,0);
  10. // draws only the two lines in wireframe mode
  11. ctx.strokeStyle = “#0000FF”;
  12. ctx.stroke();

DRAWING A SINGLE PATH MADE WITH DISCONNECTED LINES / PARTS

Try this interactive example here: http://jsbin.com/lefoze/2/edit

One path made of two disconnected lines

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // first part of the path
  4. ctx.moveTo(20,20);
  5. ctx.lineTo(100, 100);
  6. ctx.lineTo(100,0);
  7. // second part of the path, moveTo(…) is used to “jump” to another place
  8. ctx.moveTo(120,20);
  9. ctx.lineTo(200, 100);
  10. ctx.lineTo(200,0);
  11. // indicate stroke color + draw the path
  12. ctx.strokeStyle = “#0000FF”;
  13. ctx.stroke();

Drawing lines with different styles

COMMON MISTAKE: DRAWING THE SAME PATH TWICE

Let’s look at the drawing from the last example of the previous section:

DRAWING TWO PATHS WITH DIFFERENT STYLES: THE WRONG AND THE RIGHT WAY!

First, the wrong way!

In this example, we will draw the two parts of the path with different styles: the first part in wireframe mode, and the second part in filled mode.

What we will try first is to call stroke() after the first half of the path, then call fill() after the second half of the path (check this interactive example):

twice drawn path

Here is the code:

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // first part of the path
  4. ctx.moveTo(20,20);
  5. ctx.lineTo(100, 100);
  6. ctx.lineTo(100,0);
  7. // indicate stroke color + draw first part of the path
  8. ctx.strokeStyle = “#0000FF”;
  9. ctx.stroke();
  10. // second part of the path
  11. ctx.moveTo(120,20);
  12. ctx.lineTo(200, 100);
  13. ctx.lineTo(200,0);
  14. // indicate stroke color + draw the path
  15. ctx.fillStyle = “pink”;
  16. ctx.fill();

Now, the right way!

Online example: http://jsbin.com/niceqo/2/edit

two different paths

Source code:

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // first part of the path
  4. ctx.moveTo(20,20);
  5. ctx.lineTo(100, 100);
  6. ctx.lineTo(100,0);
  7. // indicate stroke color + draw first part of the path
  8. ctx.strokeStyle = “#0000FF”;
  9. ctx.stroke();
  10. // start a new path, empty the current buffer
  11. ctx.beginPath();
  12. // second part of the path
  13. ctx.moveTo(120,20);
  14. ctx.lineTo(200, 100);
  15. ctx.lineTo(200,0);
  16. // indicate stroke color + draw the path
  17. ctx.fillStyle = “pink”;
  18. ctx.fill();

This time, in order to draw the two shapes differently, we defined two separate paths. The way to do this is just to call ctx.beginPath() to start a new path. In this example, the first path has been drawn in wireframe mode, then a new path has been started that is drawn in filled mode.

Drawing lines in immediate mode

Sometimes it might be useful to draw just one line without being in another path.

It’s interesting to see how we can write a single “draw line” function that takes the start and end coordinates, the color, the line width, etc.

Here is the code:

  1. function drawLine(x1, y1, x2, y2, color, width) {
  2.     ctx.save();
  3.     // set color and lineWidth, if these parameters
  4.     // are not defined, do nothing (default values)
  5.     if(color)
  6.         ctx.strokeStyle = color;
  7.     if(width)
  8.         ctx.lineWidth = width;
  9.     // start a new path
  10.     ctx.beginPath();
  11.     ctx.moveTo(x1, y1);
  12.     ctx.lineTo(x2, y2);
  13.     ctx.stroke();
  14.     ctx.restore();
  15. }

Here is an example (see online example):

  1. drawLine(0, 0, 100, 100);
  2. drawLine(0, 50, 150, 200, ‘red’);
  3. drawLine(10, 100, 100, 10, ‘green’, 10);

Practical example: drawing arrows

  1. // Adapted from : http://stackoverflow.com/questions/808826/draw-arrow-on-canvas-tag
  2. function drawArrow(ctx, fromx, fromy, tox, toy, arrowWidth, color){
  3.     //variables to be used when creating the arrow
  4.     var headlen = 10;
  5.     var angle = Math.atan2(toyfromy,toxfromx);
  6.  
  7.     ctx.save();
  8.     ctx.strokeStyle = color;
  9.  
  10.     //starting path of the arrow from the start square to the end square
  11.     //and drawing the stroke
  12.     ctx.beginPath();
  13.     ctx.moveTo(fromx, fromy);
  14.     ctx.lineTo(tox, toy);
  15.     ctx.lineWidth = arrowWidth;
  16.     ctx.stroke();
  17.  
  18.     //starting a new path from the head of the arrow to one of the sides of
  19.     //the point
  20.     ctx.beginPath();
  21.     ctx.moveTo(tox, toy);
  22.     ctx.lineTo(toxheadlen*Math.cos(angleMath.PI/7),
  23.                toyheadlen*Math.sin(angleMath.PI/7));
  24.  
  25.     //path from the side point of the arrow, to the other side point
  26.     ctx.lineTo(toxheadlen*Math.cos(angle+Math.PI/7),
  27.                toyheadlen*Math.sin(angle+Math.PI/7));
  28.  
  29.     //path from the side point back to the tip of the arrow, and then
  30.     //again to the opposite side point
  31.     ctx.lineTo(tox, toy);
  32.     ctx.lineTo(toxheadlen*Math.cos(angleMath.PI/7),
  33.                toyheadlen*Math.sin(angleMath.PI/7));
  34.  
  35.     //draws the paths created above
  36.     ctx.stroke();
  37.     ctx.restore();
  38. }

Online example that uses the above code: http://jsbin.com/qekuqotumu/1/edit

  1. drawArrow(ctx, 10, 10, 100, 100, 10, ‘red’);
  2. drawArrow(ctx, 100, 10, 140, 140, 3, ‘black’);

DRAW NICER ARROWS?

On the Web, you will find many different ways to draw arrows.

This Web site is worth reading: http://www.dbp-consulting.com/tutorials/canvas/CanvasArrow.html. It details how to draw arrows with curved heads and different styles for the head. Note, however, that you will need to modify some parts if you want it to support different line widths, etc.

Closing a path

The ctx.closePath() method indicates that we would like a closed path: draw from the last point to the first.

  1. var canvas=document.getElementById(‘myCanvas’);
  2. var ctx=canvas.getContext(‘2d’);
  3. // Path made of three points (defines two lines)
  4. ctx.moveTo(20,20);
  5. ctx.lineTo(100, 100);
  6. ctx.lineTo(100,0);
  7. // Close the path, try commenting this line
  8. ctx.closePath();
  9. // indicate stroke color + draw first part of the path
  10. ctx.strokeStyle = “blue”;
  11. ctx.stroke();

 

Advertisements

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s