在画布上转换导致奇怪的行为

时间:2012-07-05 19:38:04

标签: javascript html5 canvas

我使用了canvas元素,并且下面的代码在没有变换的情况下正常工作,但是当我将变换放入时,红色框会在其后面绘制一个“尾巴”。奇怪的是,那条尾巴的颜色与盒子的颜色不同,并且它在浏览器与浏览器之间也有所不同(在FF中更暗)。 这是正常的吗?我想这是因为四舍五入。

function draw() {  
 var canvas = document.getElementById("canvas");
 g = canvas.getContext("2d");

 var x = 0;
 var y = 200;
 g.transform(.5,0,0,1,0,0);
 g.fillStyle = "rgb(200,0,0)";
 timer = setInterval(function() {
     if(x == 750) clearInterval(timer);
     g.clearRect(x,y,50,50);
     x ++;
     g.fillStyle = "rgb(200,0,0)";
     g.fillRect(x,y,50,50);
 }, 10);
}
<!DOCTYPE html>
<html>  
 <head>  
  <script type="text/javascript" src="test.js"></script>
 </head>  
 <body onload="draw()">
   <canvas id="canvas" width="800" height="600"></canvas>  
 </body>
</html>

1 个答案:

答案 0 :(得分:0)

缩放也适用于clearRect。每次调用setInterval回调函数时,最后绘制的矩形被clearRect完全覆盖,白色,因为X值仍然相同,但是当你调用fillRect时为了再次绘制红色矩形,X值增加1.由于你的X轴按0.5(半个像素)缩放,在偶数值时它需要另一个像素,但在奇数值上它应该是“半个”像素“,因为不存在,所以像素的两种颜色(白色和红色)被混合以试图获得平滑效果,因为假设两种颜色都在该像素上,每个像素占用一半像素。我猜大多数时候都很好,但在这种情况下,例如它不是。

So let x be 2 (forget about the y axis here, kay?)
Have a rect from x to x+50 (transformed coords are 1, 26)
Clear rect from x to x+50 (1, 26)

We end up here with a white rect from 1 to 26, right?

add 1 to x
Have a rect from x to x+50 (1.5, 26.5)

Oops, there's no such pixel 1.5, 1 it is.
Pixel one is filled with white already, nobody ordered me to clear that but I have to fill with red this same pixel.

Solution = blend colors

是的,所以你看到的尾巴是1列像素的结果,用红色+白色填充,不是完全白色到desa​​pear,也不是完全红色与矩形的其余部分混合。

解决方案是:

g.clearRect(x-1,y,50,50);

使用x-1,您将能够捕获此列像素。

希望我很清楚。

我认为音调的差异可能是由于每个浏览器中混合的实现差异,但是我总是注意到相同颜色的音调有些不同,具体取决于浏览器,而不仅仅是画布应用程序。