[whatwg] Blurry lines in 2D Canvas (and SVG)

Rik Cabanier cabanier at gmail.com
Tue Jul 23 22:19:23 PDT 2013

On Tue, Jul 23, 2013 at 6:20 PM, Glenn Maynard <glenn at zewt.org> wrote:

> (The below is about Canvas only; I'm not very familiar with SVG.  I think
> they should be two separate discussions.)

Agreed. Sorry to confuse the issue.

> On Tue, Jul 23, 2013 at 6:19 PM, Rik Cabanier <cabanier at gmail.com> wrote:
>> we've noticed that if you draw lines in canvas or SVG, they always end up
>> blurry.
>> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>> This happens because you offset 1 pixel and then draw a half pixel stroke
>> on each side. Since it covers only half the pixel, the color gets mapped
>> to
>> 50% gray.
>> You can work around this by doing an extra offset of half the
>> devicepixelratio,
> For Canvas, you should always add 0.5, since you're in the canvas
> coordinate space, before the pixel ratio is applied.

That seemed like an OK idea until I thought about it some more.
Doing a .5 scale will also affect your fills so a rect will now have
aliased borders.

Also adjusting for non-round device pixel ratio or as Kornel mentions,
having transforms will still result in blurry lines (unless you do a bunch
of math)

> This is the same coordinate system used by OpenGL and Direct3D 10 (and
> up), with pixels centered around 0.5x0.5.  That is, a pixel sits between
> 0x0 and 1x1.  If you're specifying the center of the line (eg. where the
> stroke grows outwards from), you need to add a half pixel.  (When you're
> specifying a bounding box, such as drawImage, you don't, since you're at
> the edge rather than the center of a pixel.)
> I'm not sure if there's a way to disable antialiasing for paths.
> Disabling antialiasing to allow people to specify wrong coordinates only
> seems like it would be more confusing, though.

Disabling it is not a solution. The 'crispEdges' option does this and the
results look bad.

> The only solution is to educate people about when and why they need to add
> a half pixel; even if there was a way to avoid this in general (I'm not
> sure there is, for an API with Canvas's functionality), it's much too late
> to change this.

I agree that we can't change this, but maybe we can add something to make
it better.

In PDF there is a feature called "strokeAdjust" that will make the stroke
align to pixel boundaries. Basically, if you turn it on strokeAdjust and
the stroke doesn't fill the entire pixel, that pixel isn't drawn. If
there's less than a pixel total, you expand the stroke to at least a pixel.

Apple has a Core Graphics function called "CGGStateSetStrokeAdjust" so they
would be able to implement this easily. :-)

More information about the whatwg mailing list