Strange HTML 5 canvas smoothing

I played with the canvas element and found that when I try to draw NxN homogeneous solid cells next to each other, in some configurations of width and height there are blurred white lines between them.

For example, this canvas should look black, but it contains some kind of grid, which, I assume, is the result of erroneous anti-aliasing in the browser.

Canvas showing the problem.

Suffice it to say that this error appears only in some configurations, but I would like to get rid of it forever. Is there any way around this? Have you had problems with smoothing in the canvas?

I made this script that demonstrates the problem and allows you to play with canvas sizes and number of cells. It also contains code that I use to draw cells so you can check it out and tell me that I'm doing something wrong.

var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvasWidth, canvasHeight); for (var i = 0; i < numberOfCells; ++i) { for (var j = 0; j < numberOfCells; ++j) { ctx.fillStyle = '#000'; ctx.fillRect(j * cellWidth, i * cellHeight, cellWidth, cellHeight); } } 

Thanks in advance,

Peter.

+5
source share
3 answers

After reading and trying several approaches, I decided to come up with my own. I created another (virtual) canvas that had integer sizes corresponding to the number of cells in the grid.

After drawing all the cells, I call context.drawImage() on the main canvas and pass the virtual canvas as an argument, as well as the offset and scale options so that it matches the rest of my drawing. Assuming that the browser will scale the image of the virtual canvas as a whole (rather than individual cells), I was hoping to get rid of unwanted separator lines.

Despite my efforts, the lines still exist. Any suggestions?

Here the fiddle demonstrates my technique: https://jsfiddle.net/ngxjnywz/5/

+1
source

jsFiddle: https://jsfiddle.net/ngxjnywz/2/

javascript snippet

 var cellWidth = Math.ceil(canvasWidth / numberOfCells); var cellHeight = Math.ceil(canvasHeight / numberOfCells); 

Depending on the width, height, and number of numberOfCells, you sometimes get ... say 4.2, which is 4, however this will not display correctly and will allow you to display an empty line of 1 pixel size. So, all you have to do is use the Math.ceil function, and this will cause your cellWidth and cellHeight to always be larger and you will no longer get empty rows

+4
source

The best solution is to add a stroke of 0.5 pixels wide around all the fills, using the same style as the fill and offset of the entire drawing so that you display in the center of the pixels and not in the upper left corner.

If you add scaling or translation, you will have to adjust the coordinates so that you still provide the centers for your graphic coordinates.

In the end, you can only reduce artifacts, but for many situations you cannot completely remove them.

This answer shows how to remove artifacts for an untransformed canvas. How to fill in the blanks

+2
source

Source: https://habr.com/ru/post/1238516/


All Articles