Squirrl
Squirrl

Reputation: 4966

Why is clearRect() not fully clearing fillRect()

Why is clearRect() not fully clearing fillRect() when they have the same values in this example?

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";

setInterval(function(){
	let rect = {x:Math.random()*c.width, y:Math.random()*c.height}
	ctx.fillRect(rect.x, rect.y, 5, 5);
	ctx.clearRect(rect.x, rect.y, 5,5);
},500)
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

Upvotes: 3

Views: 542

Answers (1)

Kaiido
Kaiido

Reputation: 136796

Because of antialiasing.

You are drawing at non-integer coordinates, while you can't have half pixel rendered, so the pixels colors are shaded with some transparency to give this illusion of smaller pixels than a pixel.

However, clearRect() is also subject to this antialiasing, and thus will leave some translucent pixels.

To avoid this try to always draw at pixel integers when possible, and moreover, clear the whole canvas and redraw what needs to be at every frame.

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";

setInterval(function() {
  // clear all
  ctx.clearRect(0, 0, c.width, c.height);
  // redraw what needs to be
  let rect = {
    x: Math.random() * c.width,
    y: Math.random() * c.height
  }
  ctx.fillRect(rect.x, rect.y, 5, 5);
}, 500)
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

Upvotes: 5

Related Questions