gka / chroma.js

JavaScript library for all kinds of color manipulations
https://vis4.net/chromajs/
Other
9.94k stars 543 forks source link

Incorret HCL interpolation between saturated colors and black #310

Open aarthificial opened 1 year ago

aarthificial commented 1 year ago

Description When using the hcl/lch color space for interpolating between saturated colors and black, the resulting value is not correct:

interpolate('#f00', '#000', 1, 'hcl').hex() // #5b0000 (should be #000000)

The problem occurs only if one of the colors is pure black. Increasing the brightness even sliglty results in a correct color:

interpolate('#f00', '#010101', 1, 'hcl').hex() // #010101

Similarly, if the other color has no saturation, the interpolation is also correct:

interpolate('#ccc', '#000', 1, 'hcl').hex() // #000000

Possible explanation It seems that this may be caused by the interpolator used for hcl/lch: https://github.com/gka/chroma.js/blob/cd1b3c0926c7a85cbdc3b1453b3a94006de91a92/src/interpolator/_hsx.js#L44-L49 If one of the colors has a NaN hue and lb == 0 (pure black), the saturation is taken as-is from the other color. This means that interpolate('#f00', '#000', 1, 'hcl') results in hcl(40, 104, 0) instead of hcl(40, 0, 0).

Version 2.4.2

bkahlert commented 1 year ago

@aarthificial Did you try oklch? According to https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl#oklch-vs-hsl it's better than HCL it performs better in blue colors but maybe it coincidently it of help.

aarthificial commented 9 months ago

@bkahlert Thanks for the suggestion! We use chroma.js to handle colors in Motion Canvas and this problem was reported by one of our users. I told them to use a different color space but it would be great to have it fixed here.