I noticed an interesting bug today while working on a browser-based user interface rendered with the HTML 5 <canvas> element. A little rectangle was appearing fuzzy:
Let me zoom in a bit:
Whereas it should have appeared crisp, as in this:
My first thought was that it would be due to fractional coordinates. I have years of experience with drawing APIs that force integer coordinates, so I’m used to having the fractional part of a coordinate whacked off and making up the difference when necessary in a second pass. Canvas, on the other hand, supports fractional coordinates, which I’m told is the fancy thing to do these days. (How the fraction is converted to an actual pixel is depenendent on whatever drawing system is doing the heavy lifting somewhere down the stack.) When your coordinates are fractional, you can get this kind of fuzziness.
Because the interface I’m working with involves a few layers of rendering code, ensuring that integers ruled the roost took some time. (I did this by wrapping the various canvas functions with versions that dumped their parameters before calling back to the real functions.) But after quite a bit of poking around, I found no evidence of fractional coordinates. It was around this time I saw Vlad (Mozilla’s graphics guru) walking around the office and asked for some help.
We started looking for evidence of transforms that would introduce fractional coordinates–but ultimately came up empty handed. As we went through this process, he pointed out that the <canvas> context instances are reused, so it’s a really good idea to
restore() when obtaining a canvas to avoid polluting the context:
var ctx = canvas.getContext("2d"); ctx.save(); // painting here ctx.restore();
I had assumed each call to
getContext() produced a fresh, stateless context, so this was welcome news indeed.
But, we didn’t find a source for the fractional coordinates. And then we noticed when right-clicking and selecting “View Image” from the context menu, the resulting image that was physically smaller than the browser window.
And that’s when we noticed that I had zoomed in a click using Firefox 3′s fancy full page zoom feature, which was causing the image the be scaled up, and the blurriness.
May you avoid a similar fate.