In order to correctly draw a 1px wide line, on a single pixel, you actually need to position it 0.5 pixel further. …
The problem with SVG and Canvas
SVG and canvas are awesome technologies, and are changing the way we use graphics on the web. I love working with both, and support for both keeps improving (IE9 might even support SVG!) However, they have one problem that is really getting to me, and it’s not even their fault.
You see, SVG and Canvas are based on vectors. This means that they don’t really care about the pixels they get drawn on, their graphic implementation takes care of that. And thats a problem. This is the code to draw a 1px line in canvas:
var canvas1, context1; canvas1 = document.getElementById("canvas1"); canvas1.height = 20; canvas1.width = 560; context1 = canvas1.getContext("2d"); context1.strokeStyle = '#000000'; // draw context1.moveTo(1,10); context1.lineTo(200,10); context1.stroke();
As you can see, that line is blurry. I don’t want my lines to be blurry. Luckily there is an easy fix:
context1.moveTo(1,10.5); context1.lineTo(200,10.5); context1.stroke();
Just offset with half a pixel, and it’ll render nice and sharp. This works, because in SVG and in Canvas, pixels aren’t seen as an indivisible unit. You can draw on a part of a pixel.
When you code a line to start at a certain pixel, you are actually starting the line in the top-left corner of that pixel. When that line is 1px wide, half a the line gets drawn on one pixel, and the other half on the one next to it, resulting in a blurry line.
As I said, this is’t really SVG or Canvas’ fault. SVG and Canvas should not care about pixels, because they work in vectors. The lines are blurry by design. However, the last thing a canvas or SVG developer should want is code littered with
+0.5 and currently, this is exactly what happens.
What I want
I don’t want to have to write
+0.5 all throughout my canvas or SVG generating code. I want the canvas or SVG implementation to be smart enough to know when that line is going to be unintentionally blurry, and make sure it’s not. Now, an implementation might not be able to determine this, I don’t know.
At the very least, give developers a global option to switch between the two “modes” (one being theoretically correct, the other giving sharp lines). Call it
alignToRaster (a boolean, as a property of the canvas, defaults to false) and if set to true, silently add the 0.5px for me.