Skip to content

fix: use sRGB for color picker XY conversions, add XY sliders for color_xy devices#461

Open
Mihonarium wants to merge 3 commits intoNerivec:mainfrom
Mihonarium:patch-1
Open

fix: use sRGB for color picker XY conversions, add XY sliders for color_xy devices#461
Mihonarium wants to merge 3 commits intoNerivec:mainfrom
Mihonarium:patch-1

Conversation

@Mihonarium
Copy link

Fixes #367.

(thanks claude!)

Problem

The color editor converts RGB/HSV values to CIE XY using the device gamut (e.g. Philips Hue) instead of sRGB. Since the user's screen displays sRGB, the color they pick doesn't match the XY coordinates sent to the device. E.g., selecting a saturated cyan (#00FFCC) on a Philips Hue device produces XY ≈ (0.343, 0.387), which is near white, instead of the correct XY ≈ (0.243, 0.396).

Why sRGB, not the device gamut

RGB/HSV/hex values are always sRGB; that's what web displays render. Converting these to CIE XY must use sRGB primaries so that what the user sees on screen corresponds to what the device produces. The device firmware handles mapping CIE XY to its own physical gamut internally. Using the device gamut for this conversion effectively treats sRGB colors as if they were in the device's color space, producing wrong coordinates.

This is also the reason Koenkk/zigbee-herdsman-converters#11263 produces incorrect results for non-CIE1931 gamuts — it uses the device gamut for the RGB→XY conversion in the backend converters.

Changes

src/components/editors/index.ts:

  • Add SRGB gamut definition (standard web display primaries, D65 white, sRGB gamma)
  • convertToColor now uses sRGB for all RGB/HSV/hex ↔ XY conversions

src/components/editors/ColorEditor.tsx:

  • For color_xy format: show X and Y sliders (0–0.74 and 0–0.84) with live gradient backgrounds, instead of hue/saturation sliders
  • For color_hs format: existing hue/saturation sliders unchanged

- Added SRGB gamut definition (sRGB primaries + gamma) and exported it.
- `convertToColor` now uses sRGB for all RGB/HSV/hex ↔ XY conversions instead of the device gamut
When format === "color_xy": shows X and Y sliders (range 0–0.74 and 0–0.84 respectively, step 0.001) with gradient backgrounds that sample actual CIE colors along each axis
When format === "color_hs": shows the original hue/saturation sliders as before
Both still show the hex/rgb/hsv/xyY text inputs below
Add XY color input handling to ColorEditor
@Mihonarium
Copy link
Author

image

@Nerivec
Copy link
Owner

Nerivec commented Mar 5, 2026

As mentioned in the linked issue, we need to fix the ZHC CIE handling first.
I don't think users want X/Y sliders, they know how to use a typical hue/sat slider, not this. We would no doubt get push-back on it.

Also, I don't trust anything done by AI on this.
I'd like someone with great color knowledge to take a look at both the WindFront & ZHC code, but have yet to find someone 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XY color sliders are mapped wrong?

2 participants