color.js icon indicating copy to clipboard operation
color.js copied to clipboard

Mix doesn't respect hue angle specification

Open facelessuser opened this issue 4 years ago • 5 comments

Problem

I was trying to recreate some of the examples from the CSS 5 mixing drafts, as this project seems to be a playground for expressing those ideas, and I realized I could not get mix to recognize the specified angle adjuster to use:

new Color('lch(52% 58.1 22.7)').mix('lch(NaN NaN 257.1)', 1 - 0.7523, {hue: "shorter", space: "lch"});
// lch(52% 58.1 351.6)
new Color('lch(52% 58.1 22.7)').mix('lch(NaN NaN 257.1)', 1 - 0.7523, {hue: "longer", space: "lch"});
// lch(52% 58.1 351.6)

Expectation

In the above examples, I would expect that when longer was used, the return would be:

new Color('lch(52% 58.1 22.7)').mix('lch(NaN NaN 257.1)', 1 - 0.7523, {hue: "longer", space: "lch"});
// lch(52% 58.1 80.761)

I suspect this is unintentional and should be able to replicate such examples in the color 5 spec.

facelessuser avatar Oct 08 '20 13:10 facelessuser

Yes, this project is indeed being used as a playground for CSS Color 4, CSS Color 5,CSS Color HDR and CSS Typed Object Model.

By the way why are you setting L and C to NaN? As far as I recall, we only have special handling for NaN on hue (for achromatic colors). However, yes you should be getting a different angle there; this is a bug.

new Color('lch(52% 58.1 22.7)').mix('lch(52% 58.1 257.1)', 1 - 0.7523, {hue: "longer", space: "lch"});

svgeesus avatar Oct 16 '20 17:10 svgeesus

In fact it would be nice if people could type examples straight from CSS Color 5 and they worked, instead of having to transform the syntax as you did. But that should be a separate issue.

svgeesus avatar Oct 16 '20 17:10 svgeesus

By the way why are you setting L and C to NaN?

Because it works and it is unclear that this wasn't supposed to be allowed. The code will return the other channel (for any channel) if the other is NaN.

The official docs actually do this, just not directly through the string.

// Two kinds of fade out to transparent
lime.range(new Color("transparent"));
lime.range(new Color(lime.space, [NaN, NaN, NaN], 0), {space: lime.space});

facelessuser avatar Oct 16 '20 17:10 facelessuser

Related, the API documentation for the options object for color.range() does not mention the hue option, although the interpolation docs use it in examples. And when it is not used, the default does not seem to be shorter.

svgeesus avatar Nov 04 '20 17:11 svgeesus

This issue was resolved by #338

facelessuser avatar Oct 17 '23 18:10 facelessuser