CaptainCodeman / svelte-color-select

Okhsv color select for Svelte
https://captaincodeman.github.io/svelte-color-select/
Other
30 stars 1 forks source link

Values need to be clamped to RGB / P3 gamut #9

Open drwpow opened 1 year ago

drwpow commented 1 year ago

Problem

When using the oklab prop, values aren’t clamped to the sRGB (or P3) gamut which results in the picker showing the wrong X, Y if you change the values externally:

CleanShot 2023-09-03 at 15 24 53

What’s happening here is the h, s, v values are updating correctly, however, the v is > 1 so it gets clamped to 1. This results in an “impossible” color that can’t be represented by the picker. When the square is clicked, it clamps back to sRGB space so you see the values correct again.

Solution

Find some way to clamp the colors to RGB space.

CaptainCodeman commented 1 year ago

Sounds like it would really need the high-gamut / P3 to do properly - the picker is working in the renderable / display space which simply might not match up with LAB otherwise

drwpow commented 1 year ago

Yeah the proper method is using Culori’s clampChroma(…, 'oklch') function. I’ve tested this pretty extensively and it matches up 1:1 with Björn’s “clamp chroma” method mentioned (it’s also no surprise Culori is mentioned as his preferred JS implementation). We could go that route if we want to do things the proper way.

Again, I should note that when picking colors on the canvas you can never end up with an out-of-gamut color. But if you adjusted the color outside the picker (e.g. the sliders in the example), then the canvas shows the SV square in the wrong location (the hue shouldn’t ever change though).

CaptainCodeman commented 1 year ago

Given that the purpose of the color select is to select a color, I think it's reasonable that it means you can only pick ones that are RGB values (displayable on screen), even if you want the values defined as OKLAB or OKHSV ... it's really only the demo that will have issues, where there is another way to select values that are then out of range, so I think at most it's something to document.

What would be useful is to allow RGB or full P3 range of colors though.

drwpow commented 1 year ago

it's really only the demo that will have issues

No I think there is a bug here—if you initialized the picker with an out-of-gamut color the color picker will show the wrong value. If you click on the exact same spot, it will mutate your color, which is also unexpected. Further, it won’t err, or give any indication that anything is wrong. While the demo allows you to recreate it, I think this is a common problem when using Oklab in general regardless of how you’re using it.

IMO while throwing an error is acceptable and telling users the color is out-of-gamut, fixing the bug is trivial and is a better experience.

drwpow commented 1 year ago

What would be useful is to allow RGB or full P3 range of colors though.

I also agree! And I think that’s a separate feature/enhancement.

As a semi-unrelated thought, there are 2 strategies I’ve run across when dealing with P3:

1. Treat it as a true expanded gamut

The expected way of dealing with P3, as seen with oklch.com. Basically, put the burden on the user for understanding where the limits of the sRGB gamut and the P3 gamut begin. This is necessary for photo/video work, but there’s also…

2. Let it gracefully degrade into sRGB

E.g. pretend color(srgb 1 0 0) and color(display-p3 1 0 0) are the same color even though they’re not. This is one strategy encouraged by WebKit as a nice invisible enhancement to most websites. While this application is limited to CSS, it’s actually a pretty “dumb” but elegant way of providing more rich spot color enhancements to CSS colors without having to futz with any math or color libraries. This obviously won’t work for photo/video or advanced applications like WebGL. But again, it does provide users with HDR colors without any complexity.

Reason I mention this is that having an sRGB-limited color picker doesn’t necessarily restrict users from using P3 colors—they just pick colors in an sRGB space to account for all devices. And then in external tooling they can enhance the devices that support P3 with more vibrant colors (and, for the most part, it works well, because P3 is an extension of sRGB)