-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Approach to HCT Tonal Palettes #390
Comments
My preference is to leave the CSS-specific one alone, because converging on that exact algorithm here in in SS Color 4 took a fair bit of work and other projects are depending on it. Extending the generic method to add optional parameters, such that existing code continues to work but there is more flexibility, seems a good approach. That would include adding a new HCT deltaE metric, which could be specified along with the low JND and the clamping behavior to get the desired gamut mapping result. Finally, a utility function with a method keyword, which produced the correct function call with the correct optional parameters for that specific case, would make it easier to use. |
I'm not exactly sure what is meant by this utility function, but I think I get the overall gist from your statement. I will most likely modify the non-CSS approach and extend the parameters to allow for the needed configuration to pull off tonal palettes. If you can provide an example of the expectation for the utility function request, I am more than happy to implement it, I'm just currently not certain as to what is precisely being requested. |
Instead of something like let Color2 = Color1.toGamut({method: hct.c, jnd: 0.00005, blackWhiteClamp: true}) it would be good to have a method keyword that does all that for you. |
Ah, that makes sense. Some new recognized keyword that just applies all of that. I will work on the implementation of the logic and expose some keyword that does what is asked. I won't worry too much about the name of that keyword and let the final name be decided in the review. |
@svgeesus in the current gamut mapping algorithm, we always have the original color which is then converted to the target gamut space and then the gamut space gets converted to the mapping color space. Is there a reason for this? Does it force the normalization of undefined values or something like that? Or is there no intentional reason for this? I ask because I'd like to change it so that the original color is converted to the gamut color, and then the original color is converted to the mapping color. My reason is that HCT and CAM16 have some particular cases that can be out of the visible gamut and when round-tripped will produce different colors. This is just a limit of CAM16 and CAM16-based spaces. > const { default: Color } = require("colorjs.io");
undefined
> let c = new Color('blue').to('hct').set('t', 5);
undefined
> c.coords
[ 282.762176394358, 87.22803916105873, 5 ]
> c.to('srgb').to('hct').coords
[ 102.76217639435498, -59.52229328095306, 52.175560526116016 ] In order to get good tonal maps, we have to gamut map the colors in HCT, ideally, we'd like to use the original color without round-tripping it if it is already in HCT. If there was a reason for this round tripping, I'd like to know the reason and address it directly opposed to introducing this round-tripping. Below I will illustrate the results of keeping things the way they are vs my proposal. This can be particularly problematic in some low lightness cases. ![]() ![]() |
In the CSS GMA there is no such step: after checking whether the destination space is unbounded, the second step is to convert the color to the mapping colorspace ( I don't think there is a reason for having a two-step conversion; it is mixing up an in-gamut check with the GMA and would be better as two parallel conversion (original to target, to see if it is in gamut; then original to mapping spec if needed). And I agree that the current two-step conversion can introduce round-off error. |
Now that the HCT color space is in, one of the reasons for people's interest is the ability to make tonal palettes.
To do this, we need to be able to gamut map in HCT in order to pull off values that align close to Material's. This issue is meant to discuss how Color.js would like to approach this.
Color.js currently has two approaches to gamut mapping. One that is specifically CSS centric, the other more generic for LCh-like spaces.
In order to calculate tonal palettes that are similar to Material we need a few things.
Currently, Color.js does not allow changing the JND of either approach. The CSS approach provides the clamping of SDR white and black that we need, but the generic approach does not. The generic method allows for giving an arbitrary LCh space which we need. Ideally, we'd like to not leave the HCT color space due to the high conversion cost to convert out of HCT for distancing, but maybe this is not necessarily required. If we did want to use a different distancing more HCT-centric, there is no interface to swap out different distancing algorithms for gamut mapping either.
So, my question is how we'd like to approach this.
The text was updated successfully, but these errors were encountered: