If we want to create the best quality images that we can using the Canvas API, we must make sure that they are extremely sharp and in-focus. Blurry lines can ruin an image.
In this article, we will look at the problem of drawing a simple straight line and how without understanding how canvas pixels are rendered, we might accidentally reduce the quality of our image.
To illustrate this issue, we have drawn three lines on a canvas. The two lines on the left have been drawn using
lineWidth = 1. The line of the right has been drawn with
rect() and has a single pixel width. If we look closely at the three lines, we can see that the first line on the left looks fuzzy compared to the other two lines.
If you want to zoom in and have a look more closely at the difference in how clean these lines are drawn. Go to the
styles.css file and add
width: 400px under the style
border: 1px solid darkorange;. This will force the canvas points to now be drawn at double their default size of
Why is the first line blurry?
To understand why this is happening, we need to consider how canvas points are drawn. If we look at the grid below, we can see the canvas coordinate system and how this corresponds to the actual pixels used to represent the canvas. We have drawn a single pixel dot at
(1,1). From the image you can see that the way this dot has been drawn is that the pixel that represents
(1,1) is actually the physical space between coordinates 1 and 2 on both the x axis and the y axis. It is not actually physically possible to draw a dot at exactly
Going back to our example, when we draw the line on the right using a rectangle with the commands
fill() , we are actually telling the canvas to fill in the space between coordinates
140 & 141. As the space between
140 & 141 is represented by exactly one pixel (when we haven't zoomed in), we are able to draw a clean line.
When we are using
stroke() to draw the paths, the canvas will attempt to draw the line at precisely the correct coordinate. In our example, we are drawing the 1st line (on the left) vertically at exactly
60px. But based on how the coordinate system works, there is no real pixel at
x = 60 rather the real pixel is between
60 & 61. The canvas will still try to draw a vertical line at exactly
x = 60 and the only way it can do this is mathematically shading the pixels either side of the position
x = 60 and it is this which causes the line to look fuzzy.
How can we fix the blurry line?
We can solve the blurry line by shifting the line position to
x = 59.5. The second (middle) line demonstrates this by using a position of
x = 79.5. This position draws a clean line as a
1px wide vertical line positioned at
x = 79.5 will use the real pixel between
79 & 80 will not need to shade any surrounding pixels.
Try adjusting the x value of the first line to see how the image can be improved.
I have to put my pen down now. 🤸♂️
If you like my approach to explaining things, consider having a look at the course below.
Try the Complete HTML Canvas course...
The course covers all aspects of the HTML Canvas API. You will learn and practice with live code examples and challenges making sure that you truly are mastering each technique. The course is completely free.