Canvas html5画布中单个像素上的clearRect()不';t实际上将alpha设置为0

Canvas html5画布中单个像素上的clearRect()不';t实际上将alpha设置为0,canvas,html5-canvas,Canvas,Html5 Canvas,我正在html5画布上手工绘制单个像素。我只使用纯黑色和纯白色。仅稍微简化: var canvas = document.querySelector(".main-canvas"); var ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; var isNonNegativeInteger = function(val) { return Number.isFinite(val) && val

我正在html5画布上手工绘制单个像素。我只使用纯黑色和纯白色。仅稍微简化:

var canvas = document.querySelector(".main-canvas");
var ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false;

var isNonNegativeInteger = function(val) {
  return Number.isFinite(val) && val % 1 === 0 && val >= 0;
};

var paintPixel = function(x, y) {
    if (!isNonNegativeInteger(x) ||
        !isNonNegativeInteger(y) ) {
        debugger;       
    }
    ctx.fillRect( x, y, 1, 1 );
};

var clearPixel = function( x, y ) {
    if (!isNonNegativeInteger(x) ||
        !isNonNegativeInteger(y) ) {
        debugger;       
    }
    ctx.clearRect( x, y, 1, 1 );
};
我只传递整数作为x和y坐标。是的,我绝对肯定,我已经做了测试

我不是在操纵RGB。所有像素都保持黑色。我只是在操纵阿尔法。我发现,经过大量的绘制和清理,前后反复,在调用
clearRect()
时,被
fillRect()设置为完全不透明的黑色像素实际上没有将其alpha重置为零

我之所以知道这一点,是因为当我在受影响的像素邻域中调用
ctx.getImageData()
时,我看到像素数据alpha值中散布着低但非零的alpha值(3、5或12等)。这是。。。疯狂的制造。有趣的是,我还看到一些黑色像素的非255 alpha值,它们也有问题,但视觉攻击性不如“脏”白色

这些是大像素网格,每帧有数千个绘制调用。因此,我不愿意使用
getImageData()
putImageData()
手动设置alpha,因为它们速度很慢。问题在于
clearRect()
没有按照tin上的说明执行


非常感谢您的建议。

真奇怪,我能想到的唯一原因是您的x和y坐标不是
int
。 在浮动位置绘制确实会在
clearRect
上创建抗锯齿伪影:

var canvas=document.createElement('canvas');
document.body.appendChild(画布);
var ctx=canvas.getContext('2d');
ctx.textb基线=“中间”
var paintPixel=函数(x,y){
ctx.fillRect(x,y,1,1);
};
var clearPixel=函数(x,y){
ctx.clearRect(x,y,1,1);
};
var i=0;
对于(i=0;i<25;i+=0.1){
像素(i,10);
清晰像素(i,10);
}
ctx.fillText('float',30,10)
对于(i=0;i<25;i++){
像素(i,30);
清晰像素(i,30);
}
ctx.fillText('int',30,30)
//另一种解决方案可能是使用globalCompositeOperation
var gCOClear=函数(x,y){
ctx.globalCompositeOperation='destination out';
ctx.fillRect(x,y,1,1);
ctx.globalCompositeOperation='source over';
}
对于(i=0;i<25;i+=0.1){
像素(i,50);
gCOClear(i,50);
}
ctx.fillText('gCO float',30,50)
对于(i=0;i<25;i++){
彩色像素(i,70);
gCOClear(i,70);
}

ctx.fillText('gCO int',30,70)
这真的很奇怪,我能想到的唯一原因是你的x和y坐标不是
int
。 在浮动位置绘制确实会在
clearRect
上创建抗锯齿伪影:

var canvas=document.createElement('canvas');
document.body.appendChild(画布);
var ctx=canvas.getContext('2d');
ctx.textb基线=“中间”
var paintPixel=函数(x,y){
ctx.fillRect(x,y,1,1);
};
var clearPixel=函数(x,y){
ctx.clearRect(x,y,1,1);
};
var i=0;
对于(i=0;i<25;i+=0.1){
像素(i,10);
清晰像素(i,10);
}
ctx.fillText('float',30,10)
对于(i=0;i<25;i++){
像素(i,30);
清晰像素(i,30);
}
ctx.fillText('int',30,30)
//另一种解决方案可能是使用globalCompositeOperation
var gCOClear=函数(x,y){
ctx.globalCompositeOperation='destination out';
ctx.fillRect(x,y,1,1);
ctx.globalCompositeOperation='source over';
}
对于(i=0;i<25;i+=0.1){
像素(i,50);
gCOClear(i,50);
}
ctx.fillText('gCO float',30,50)
对于(i=0;i<25;i++){
彩色像素(i,70);
gCOClear(i,70);
}

ctx.fillText('gCO int',30,70)
如果您仍然保持所有像素为黑色,则可以使用fillRect。你会在任何地方改变变换矩阵吗?您测试过多个浏览器吗?如何使用fillRect“擦除”?将ctx.fillStyle设置为零alpha只意味着填充完全没有效果。没有变换矩阵。在FF和Chrome中看到类似的结果。是关于这个的更多信息。不,我绝对不建议这样做。阅读下面的答案,以及对问题的评论。有两件事需要仔细考虑。1.低alpha值(如果仍然保持所有像素为黑色,则可以使用fillRect。是否在任何位置更改变换矩阵?是否测试过多个浏览器?如何“擦除”使用fillRect?将ctx.fillStyle设置为零alpha只意味着填充没有任何效果。没有变换矩阵。在FF和Chrome中看到类似的结果。更多信息。不,我绝对不建议这样做。阅读下面的答案和对问题的评论。有两件事需要考虑。1.低alpha值(谢谢,但当我说我确定参数是整数时我是认真的。)我编辑了这个问题,希望能澄清。如果我把它改为“擦除”通过使用不透明白色绘制,或使用
ctx.globalCompositeOperation='destination out'
这两种方法都可以修复FF中的重影,但我仍然在眨眼中得到它。@Ben Oups错过了这一行:-/我会给出答案,因为它可能会引起未来读者的兴趣。你能添加一个实例吗?gCO工作而不是
cl似乎很奇怪耳环
甚至更重要的是,它只对FF有效。谢谢,但我说的是真的,我确信参数是整数。我编辑了这个问题,希望能澄清。如果我把它改为“擦除”通过使用不透明白色绘制,或使用
ctx.globalCompositeOperation='destination out'
这两种方法都可以修复FF中的重影,但我仍然在眨眼中得到它。@Ben Oups错过了这一行:-/我会给出答案,因为它可能会引起未来读者的兴趣。你能添加一个实例吗?gCO工作而不是
cl似乎很奇怪耳环
甚至更重要的是,它只适用于FF。