[whatwg] Canvas gradients color interpolation - change to premultiplied?

L. David Baron dbaron at dbaron.org
Tue Nov 23 15:03:33 PST 2010

On Tuesday 2010-11-23 22:09 +0000, Philip Taylor wrote:
> On Tue, Nov 23, 2010 at 8:43 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
> > Right now, canvas gradients interpolate their colors in
> > non-premultiplied space; that is, the raw values of r, g, b, and a are
> > interpolated independently.  This has the unfortunate effect that
> > colors darken as they transition to transparent, as "transparent" is
> > defined as "rgba(0,0,0,0)", a transparent black.  Under this scheme,
> > the color halfway between "yellow" and "transparent" is
> > "rgba(127,127,0,.5)", a partially-transparent dark yellow, rather than
> > "rgba(255,255,0,.5)".*
> If you define the gradient as interpolating from solid yellow to
> transparent black, I'd expect that it *should* be semi-transparent
> blackish-yellow in the middle.
> If you want it to be pure yellow, don't use a keyword which is
> explicitly specified as transparent black - define the gradient from
> rgba(255,255,0,1) to rgba(255,255,0,0) instead. Then you'll get
> rgba(255,255,0,0.5) in the middle.

Sure, you can solve that particular case.  However, if neither of
the endpoints is precisely transparent, and you're changing both
color and alpha components, you'll still get an ugly effect with the
current rules, and one that you can't work around.  (I experimented
with both methods when implementing CSS transitions of colors, and
went with premultiplied.
http://dbaron.org/css/test/2009/transitions/transitions-alpha makes
it look like WebKit has now switched to premultiplied.)

> That sounds like SVG gradients *can't* be using premultiplied colours.

Yes, because SVG doesn't have RGBA colors; it has RGB colors (in
stop-color) and a separate stop-opacity property/attribute.  So the
choice doesn't apply to SVG.

> Maybe CSS should have originally used the keyword "transparentblack"
> instead of "transparent" (though the distinction didn't matter before
> gradients existed) - changing the gradient algorithm solely to work
> more intuitively when people happen to use that one particular
> incorrectly-named keyword seems backwards, and a mistake in CSS.

It's not only the 'transparent' keyword; it affects all cases of
gradients between colors with different alpha values and different
color values.  And in cases where one of the endpoint alphas is not
0, it's not possible to get the correct (premultiplied) result with
a gradient computed in nonpremultiplied space.


L. David Baron                                 http://dbaron.org/
Mozilla Corporation                       http://www.mozilla.com/

More information about the whatwg mailing list