JavaScript Canvas Fill and Holes
Written by Ian Elliot   
Monday, 08 March 2021
Article Index
JavaScript Canvas Fill and Holes
Filling Holes

For example, if we change the star path fill rule to:

ctx.fill(Path1, "nonzero");

then the hole is filled:

However, this is only because the two disconnected paths are drawn in the same sense – i.e. anticlockwise. If the second triangle is changed to:

Path1.moveTo(50, 110);
Path1.lineTo(100, 60);
Path1.lineTo(0, 60);
Path1.lineTo(50, 110);

it is drawn in the opposite sense to the first triangle and the winding number of a point in the middle is now zero and hence the hole is not filled:

So what happens to a “hole” in a shape depends on which way you draw the disconnected path that fills it.

How do you work out the fill rule to use in any given case?

Most often you simply try it out and see. If a hole that you want to have unfilled is being filled then you can either change the direction you draw it in or try the odd-even rule.

For example, consider the space ship path introduced in the previous chapter. We could add a “port hole” by adding a circle path to it:

var Path1 = new Path2D("m 98.684674,206.63833 
c 2.891926,-25.77092 -1.958475,-65.0136 -13.037221,
 -73.92172 -11.072474,8.90817 -17.526591,48.1508 -14.634563,
  73.92172 -9.479011,8.46903 -9.015897,17.40218 -9.068381,29.71617 
l 5.92022,-0.074 
c 0,0 2.493141,-15.15787 5.105513,-16.98251 
l 3.15542, 8.06751 -1.537022,9.15649 
c 13.277647,-0.17974 7.242537,-0.17974 20.52018,0 
l -1.537022,-9.15649 3.15552,-8.06751 
c 2.979241,2.08093 3.605942,17.00168 3.605942,17.00168 
l 6.61799,0.0548 
c -0.0526,-12.31399 1.21238,-21.24714 -8.266576,-29.71617 z");
var Path2 = new Path2D();
Path2.arc(85, 180, 10, 0, 2 * Math.PI, 0);
ctx.fill(Path1, "nonzero");

If we fill the path using the non-zero rule then the hole will not be filled if the circle is drawn in the same direction as the outer path:

However, if you change the arc function to:

Path2.arc(85, 180, 10, 0, 2 * Math.PI, 1);

i.e. draw the circle in the opposite direction, then the port hole will be filled in.

In chapter but not in this extract:

  • 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
      Extract: SVG Paths
      Extract: Bezier Curves
  4. Stroke and Fill
      Extract: Stroke Properties 
      Extract: Fill and Holes
      Extract: Gradient & Pattern Fills
  5. Transformations
      Extract: Transformations
      Extract: Custom Coordinates 
      Extract  Graphics State
  6. Text
      Extract: Text, Typography & SVG 
      Extract: Unicode
  7. Clipping, Compositing and Effects
      Extract: Clipping & Basic Compositing
  8. Generating Bitmaps
      Extract:  Introduction To Bitmaps
      Extract :  Animation 
  9. WebWorkers & OffscreenCanvas
      Extract: Web Workers
      Extract: OffscreenCanvas
  10. Bit Manipulation In JavaScript
      Extract: Bit Manipulation
  11. Typed Arrays
      Extract: Typed Arrays 
  12. Files, blobs, URLs & Fetch
      Extract: Blobs & Files
      Extract: Read/Writing Local Files
      Extract: Fetch API **NEW!
  13. Image Processing
      Extract: ImageData
      Extract:The Filter API
  14. 3D WebGL
      Extract: WebGL 3D
  15. 2D WebGL
    Extract: WebGL Convolutions




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.

kotlin book



or email your comment to:

Last Updated ( Monday, 08 March 2021 )