I am manually painting individual pixels in html5 canvas. I'm only using pure black and pure white. Simplifying only somewhat:
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 );
};
I am only passing integers in as x and y coordinates. Yes, I'm absolutely sure, I've put in a test.
I'm not manipulating RGB. All the pixels stay black. I'm just manipulating alpha. What I am finding is that after a great deal of painting and clearing, with lots of back-and-forth, there is a faint visual "ghosting" where the black pixels that were set to fully opaque by the fillRect()
are not actually having their alpha reset to zero when clearRect()
is called.
I know this because when I call ctx.getImageData()
in the affected pixel neighborhood, I see low but non-zero alpha values (3, 5, or 12 etc) sprinkled in the pixel data alpha values. This is... crazy-making. Interestingly, I also see some non-255 alpha values for the black pixels, which are also problematic but less visually offensive that the "dirty" whites.
These are big pixel grids, with thousands of draw calls per frame. So I am reluctant to use getImageData()
and putImageData()
to manually set the alpha because they are slow. The problem is just that clearRect()
is not doing what it says on the tin.
Any suggestions very appreciated.