Re: [CSS3-images] premultiplied alpha (was rotate(<angle>[, <translation-value>, <translation-value>]))

On Tue, Feb 21, 2012 at 10:40 AM, Rik Cabanier <cabanier@gmail.com> wrote:
>> > I suggest that if the extra two arguments are left in the spec (which
>> > I'm still not a fan of), an extra special case be added to the
>> > transitions part so that it works as expected.  Transitioning from
>> > 'none' to rotate3d(0, 0, 1, 45deg) rotates only around the z-axis as
>> > expected, and transitioning a color from green to transparent
>> > shouldn't make it black in between even though you're technically
>> > going from rgba(0, 128, 0, 1) to rgba(0, 0, 0, 0).  Likewise,
>> > transitioning from none to rotate(45deg, 10px, 10px) should be treated
>> > like transitioning from rotate(0deg, 10px, 10px).  Anything else is
>> > not expected, IMO.
>>
>> Note that we fixed the color transition by specifying that it happens
>> in premultiplied space; that's not the same thing as what you're
>> asking for.
>
> specifying premultiplied alpha to fix the issue seems odd.
> It seems that the issue is really how to you handle the  'transparent'
> keyword. Because transparent is specified as (0,0,0,0) you transition the
> color values  as well.
> So, non-premultiplied red->transparent, the midpoint of your gradient
> becomes (0, .5, 0, .5) which after compositing with white becomes (.5, .75,
> .5) which is too dark.
> In premultiplied space, you end up with (.5, 1, .5) which is what you want.
>
> However by forcing premultiplied space, you can no longer go from 'yellow'
> to 'transparent red' because the 'red' value is removed when you multiply by
> 0.
>
> Was this discussed and deemed OK? I tried to find it in the archives but
> couldn't find it.
> Sorry if this was already decided.

Yeah, it was discussed.

Your suggestion of treating 'transparent' specially ends up being
kinda weird, since you can have a transition like "red 0%, transparent
50%, yellow 100%" - you'd have to treat it kinda like "red 0%,
rgba(255,0,0,0) 50%, rgba(255,255,0,0) 50%, yellow 100%".  You
couldn't just do a direct translation internally, though, because the
behavior of those two gradients is quite different when you animate
them.  Additionally, more complex gradients in the future may not even
be able to do this simple hack - if the stops are placed in 2d, like a
mesh gradient, you can't easily split it into "before" and "after"
segments.

This would also be inconsistent with the current definition of
'transparent', which is currently just rgba(0,0,0,0), and with
Transitions, which does color ramps in premultiplied rgba space.

Overall, you only see a difference between the two modes if you're
purposely changing both the color and the opacity, like in your
example of yellow to transparent red.  These are rare compared with
the simpler case of just going to or from 'transparent'.  When they
are desired, they can be done by manually curving through the
color-space with a couple additional stops.

For example, check out this fiddle
<http://jsfiddle.net/tabatkins/DCWax/1/>.  (I had to do the gradient
in canvas, as current impls in FF and WebKit browsers are
non-premultiplied.)  Just adding a single additional stop gets you
decently close.  Adding three additional stops gives you a result
visually indistinguishable from the non-premultiplied version without
very close study.


Brian: Your examples won't work.  Note that "rgba(100%,0,0,.001)"
turns into "pre-rgba(.1%, 0, 0, .001)", which is almost
indistinguishable from "pre-rgba(0,0,0,0)", so you'd get basically
identical color ramps.  You need to space out the extra stops so you
actually approximate a curve through the space.

~TJ

Received on Tuesday, 21 February 2012 21:53:28 UTC