JavaScript Canvas Stroke Properties
Written by Ian Elliot   
Monday, 10 February 2020
Article Index
JavaScript Canvas Stroke Properties

The problem with miter joins is that for lines that meet at very sharp angles the miter can be very long – often longer than the lines themselves. To keep this under control there is another drawing context property you can set, miterLimit. This sets the maximum distance between the inner and outer corners if the miter was drawn. The default is 10 and if the miter is longer than this it isn’t drawn and a bevel is used:


This raises the question, what is a bevel? It simply draws a line between the two outer corners of the lines and fills in the triangle:


Finally round draws a disc centered on the common endpoint with a radius equal to the thickness of the lines.


For example:

var path1 = new Path2D();
path1.moveTo(100, 300);
path1.lineTo(500, 300);
path1.lineTo(100, 350);
ctx.lineJoin = "miter";
ctx.lineWidth = 10;
ctx.miterLimit = 100;



If you set miterLimit to 10 the result is:


If you set lineJoin to bevel you get the same result:

var path1 = new Path2D();
path1.moveTo(100, 300);
path1.lineTo(500, 300);
path1.lineTo(100, 350);
ctx.lineJoin = "bevel";
ctx.lineWidth = 10;


Changing lineJoin to “round”

ctx.lineJoin = "round";

gives the following result:


The final way we can control the way a path is stroked is to set a dash pattern using the setLineDash function. This accepts an array that specifies how long the dash and spaces should be in co-ordinate units. For example, [4,8] sets a dash 4 units long followed by an 8 unit space. If you specify an odd number of elements in the array, the array is doubled in length to make it even. For example, [4,8,2] becomes [4,8,2,4,8,2]. You can also specify the current dash array using the getLineDash function. To set the line back to solid use an empty array:


There is one last control you can use, the lineDashOffset. This starts the dash pattern at the co-ordinate given by the offset. Notice that the offset is relative to the dash pattern and just indicates where to start the pattern.

For example:

var path1 = new Path2D();        
path1.moveTo(0, 50);
path1.lineTo(300, 50);
ctx.setLineDash([4, 16]);

draws a line with dashes of 4 pixels followed by a 16-pixel space.


If we set the offset to 4 then the pattern starts with the 16-pixel space. If we set it to 2 then the pattern starts halfway though the first 4-pixel dash:


Although we have yet to deal with animation, the “marching ants” program is too good to miss. All that happens is that you animate a line by changing the dash offset by one each time. For example:

var ctx = document.body.
  appendChild(createCanvas(600, 600)).getContext("2d");
var path1 = new Path2D();
path1.rect(0, 50, 200, 200);
var offset = 0;
ctx.setLineDash([4, 2]);
function march() {            
     offset = (offset+1) % 16;
     ctx.clearRect(0, 0, ctx.canvas.width, 
ctx.canvas.height); ctx.lineDashOffset = offset; ctx.stroke(path1); requestAnimationFrame(march); } march();

This repeatedly draws the dashed line after changing the offset by one. The effect is very good for so little effort. See the live listing for a demo.

In chapter but not in this extract:

  • Antialiasing
  • Fill, Stroke and the Painter’s Algorithm
  • Holes and Fill
  • Gradient Fills
  • Pattern Fills


  • The stroke function simply colors the outline of the path, whereas fill colors all of the points in the interior of the path.

  • Color can be specified by name, RGB components or HSL.

  • Alpha values control the transparency of the color, with 1.0 being opaque and 0.0 being completely transparent.

  • For stroke you can set the lineWidth, lineCap, lineJoin and lineDash.

  • Anti-aliasing makes drawing look smoother, but it can cause unexpected results for small details. It cannot be disabled.

  • The simplest way of combining old and new colors is the painter’s algorithm, which allows the latest color to cover up the old.

  • Determining what is a “hole” in a closed path is difficult. There are two general rules, odd-even and non-zero winding, and they are both valid ways of defining a hole.

  • As well as solid color fills, you can also use linear gradient and radial gradient fills.

  • Pattern fills allow you to use any bitmap as a sort of “wallpaper” for the interior of paths.





Now available as a paperback or ebook from Amazon.

JavaScript Bitmap Graphics
With Canvas




  1. JavaScript Graphics
  2. Getting Started With Canvas
  3. Drawing Paths
      Extract:  Basic Paths 
  4. Stroke and Fill
      Extract: Stroke Properties 
  5. Transformations
      Extract: Transformations 
  6. Text
      Extract: Text, Typography & SVG 
  7. Clipping, Compositing and Effects
      Extract: Clipping & Basic Compositing 
  8. Generating Bitmaps
      Extract:  Introduction To Bitmaps **NEW!
  9. WebWorkers & OffscreenCanvas
      Extract: OffscreenCanvas
  10. Bit Manipulation In JavaScript
  11. Typed Arrays
  12. Files, blobs, URLs & Fetch
  13. Image Processing
      Extract: ImageData 
  14. 3D WebGL
  15. 2D WebGL
    Extract: WebGL Convolutions 

Related Articles

Reading A BMP File In JavaScript

Getting Started With SVG

SVG, JavaScript and the DOM

Getting Started with Box2D in JavaScript






To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on, Twitter, Facebook or Linkedin.





or email your comment to:

Last Updated ( Monday, 10 February 2020 )