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.

Leave a Reply

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