Why clearRect Might Not be Clearing the Canvas Pixels

Sometimes the clearRect(x, y, width, height) method on the canvas context might not erase the previous graphics drawn. This usually happens when we’re drawing paths using methods like lineTo(), arc(), rect(), etc. and then stroking them with stroke() or filling their content area using fill(). Here’s an example of what I’m trying to convey.

The solution to this problem is actually quite simple but the issue itself can cause major headache if you’re unable to nail it. We basically have to call the beginPath() method on the 2D context. This method will create a new path and all the drawing functions called later will be directed to it. If we do not call beginPath() (and then preferably closing that using closePath()), then all the drawing commands called will stack up in the memory and every time stroke() or fill() is called, it’ll draw all the graphic paths.

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

The stacking up of all the previous path drawing functions due to not closing the paths (with beginPath() and closePath()) and hence not getting cleared (with clearRect()) can lead to unpleasant results in animations. Here’s an image of what you can expect for a rect() call with stroke() in such a situation.

HTML5 Canvas Path Stack

Finally, here’s the fixed version of the demo linked above:

(function () {
  var canvas = document.querySelector('canvas');
  var ctx = canvas.getContext('2d');
  
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  
  ctx.beginPath(); //
  ctx.rect(50, 50, 100, 100);
  ctx.stroke();
  ctx.closePath();
  
  ctx.beginPath(); //
  ctx.moveTo(350, 50);
  ctx.lineTo(400, 100);
  ctx.stroke();
  ctx.closePath();
  
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath(); //
  ctx.rect(100, 100, 100, 100);
  ctx.stroke();
  ctx.closePath();
  
  ctx.beginPath(); //
  ctx.moveTo(450, 50);
  ctx.lineTo(500, 100);
  ctx.stroke();
  ctx.closePath();
  
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  ctx.beginPath(); //
  ctx.rect(150, 150, 100, 100);
  ctx.stroke();
  ctx.closePath();
  
  ctx.beginPath(); //
  ctx.moveTo(550, 50);
  ctx.lineTo(600, 100);
  ctx.stroke();
  ctx.closePath();
  
}());

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

6 thoughts on “Why clearRect Might Not be Clearing the Canvas Pixels”

  1. Hello,

    I tried your fixed version (calling the function by the unload event of canvas).

    Commenting out all the closePath() instructions left the result unchanged (one square and one line only) !

    Searching for the closePath() reference I found that this command essentially draws a line to the first point of the path. So for a square and a line no difference should be noticed !

    Could it be possible the issues you mention only appear in specific browsers ? (I tried it with the Smultron preview.)

    Am I wrong with this ?

    Best regards,

    L. Schellenberg

    1. You’re actually right. closePath() is not essential to solve this problem. All it does is creates a path from the current point to the point where the drawing started.

  2. Thank you so much! I was having an issue where clearRect() was working fine with Chrome and not with IE11. I added beginPath() and closePath() as you suggested and that solved it!

  3. Fixed a nasty problem for me. IE seems to be the only browser susceptible to this but I think that using the beginPath(0 and closePath() is a good programming practice. Thanks for saving the day!

Leave a Reply to Shivang Cancel reply

Your email address will not be published. Required fields are marked *

*