I'm a bit confused with the way the canvas element anti-aliases text and am hoping you all can help.
In the following screenshot the top "Quick Brown Fox" is an H1 element and the bottom one is a canvas element with text rendered on it. On the bottom you can see both "F"s placed side by side and zoomed in. Notice how the H1 element blends better with the background:
Here's the code I'm using to render the canvas text:
var canvas = document.getElementById('canvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.font = '26px Arial';
ctx.fillText('Quick Brown Fox', 0, 26);
}
Is it possible to render the text on the canvas in a way so that it looks identical to the H1 element? And why are they different?
Matt, I sat with the (same/similar) problem last week, which, in my case, turned out to be because of differences in pixel densities on the devices I was testing; I wrote about it tonight - http://joubert.posterous.com/crisp-html-5-canvas-text-on-mobile-phones-and
The link at posterous is dead, so here is the gist with the source code: https://gist.github.com/joubertnel/870190
And the snippet itself:
Here's a way of doing sub-pixel rendering for any canvas content (text, images, vectors, etc). http://johnvalentine.co.uk/archive.php?art=tft.
There's scope for fine-tuning, but it's a big gain for a simple method.
Answering my own question:
It is possible using the technique demonstrated on this site:
https://bel.fi/alankila/lcd/
The only problem is that its too slow to implement in a production app. If anyone runs across a faster way please let me know.
This is generically called subpixel anti-aliasing, or ClearType on Windows. I'm not aware of any OS/browser combinations that currently support this for Canvas.
I'd be interested to see some tests using sub-pixel offsets for the text to see if any browsers even use pixel-based hinting of the font rendering (aligning ascenders on pixel boundaries, for example). My assumption would be no.
Edit: My assumption was wrong; it would appear that Safari, Chrome, and Firefox all utilize some pixel font hinting. Safari and Chrome appear the same, snapping to whole pixel boundaries, but are different from Firefox (snapping to half-pixel boundaries?). See the visual results of testing (on OS X) here: http://phrogz.net/tmp/canvas_text_subpixel.html
It's now possible to get sub-pixel font rendering by creating an opaque canvas context. In Safari and Chrome you can get this using this snippet:
var ctx = canvas.getContext("2d", {alpha: false})
I found this from this blog post.