Skip to content
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

Add CSS toGamut algorithm #344

Merged
merged 10 commits into from
Nov 16, 2023
Merged

Conversation

jamesnw
Copy link
Contributor

@jamesnw jamesnw commented Nov 14, 2023

This implements the CSS Color 4 Algorithm, as demo'ed in #154, and specified in https://drafts.csswg.org/css-color/#css-gamut-mapping.

Remaining:

  • Tests
  • Documentation

src/toGamut.js Show resolved Hide resolved
src/toGamut.js Outdated Show resolved Hide resolved
api/api.json Show resolved Hide resolved
api/api.json Show resolved Hide resolved
src/toGamut.js Outdated Show resolved Hide resolved
types/src/toGamut.d.ts Outdated Show resolved Hide resolved
src/toGamut.js Outdated Show resolved Hide resolved
@svgeesus
Copy link
Member

Time to un-draft this PR?

I see there are comments from @jgerigmeyer which should be addressed

@jamesnw jamesnw marked this pull request as ready for review November 16, 2023 17:25
@jamesnw
Copy link
Contributor Author

jamesnw commented Nov 16, 2023

@svgeesus Marked as ready for review. Between @jgerigmeyer and I, all of the outstanding comments are resolved.

I'll note that there aren't tests for this yet. I see tests are currently transitioning, but I'm happy to add some tests. Although, I'd be likely using my implementation as both the source of truth and the system under test, as I'm not aware of a source for confirmed outputs from the algorithm.

src/toGamut.js Outdated Show resolved Hide resolved
Comment on lines +161 to +166
if (coord < spaceCoord.range[0]) {
return spaceCoord.range[0];
}
if (coord > spaceCoord.range[1]) {
return spaceCoord.range[1];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: It feels this logic can be simplified, but couldn't come up with a refactor off the top of my head.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered a clamp function like return Math.min(Math.max(coord, spaceCoord.range[0]), spaceCoord.range[1]);. I went with clarity over brevity, but could easily switch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a clamp function is correct (they don't 100% have the same semantics as this code), I think the best course of action is to define a clamp(min, value, max) in util.js, and then use it here.

@svgeesus
Copy link
Member

Although, I'd be likely using my implementation as both the source of truth and the system under test, as I'm not aware of a source for confirmed outputs from the algorithm.

Right, that has been a problem for a while. Safari has the CSS GMA in there (from when it was needed for conversion to HSL or HWB) but it might be an older iteration.

Testing framework is now stable, and easier to write to without all the copy-paste boilerplate that we had previously.

@svgeesus svgeesus merged commit 496102a into color-js:main Nov 16, 2023
5 checks passed
@jgerigmeyer jgerigmeyer deleted the css4-gamut-mapping branch November 16, 2023 19:02
jgerigmeyer added a commit to oddbird/color.js that referenced this pull request Nov 16, 2023
* main:
  Add CSS toGamut algorithm (color-js#344)
  Accept "Lightness" for lab space first channel name (color-js#348)
  Fix type def for MixOptions (color-js#347)
  Add CJS file to /fn entry and fix legacy builds (color-js#349)

// The reference colors to be used if lightness is out of the range 0-1 in the
// `Oklch` space. These are created in the `Oklab` space, as it is used by the
// DeltaEOK calculation, so it is guaranteed to be imported.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use a reference to the color space then. Using string ids requires color space registration, which breaks tree-shaking. Can't remember if we do something special for basic color spaces like this one, but I don't think so,

@jamesnw
Copy link
Contributor Author

jamesnw commented Nov 16, 2023

@LeaVerou I'll open a new PR. I'm also seeing an issue with the code, where toGamut is returning out of gamut colors in some instances- see https://deploy-preview-344--colorjs.netlify.app/apps/convert/?color=color(display-p3%201%200.78%200.86)&precision=6. In sRGB, the gamut mapped version is out of gamut.

It appears that min approaches max without finding a fit. I'm assuming it's with my implementation of the algorithm, and not the algorithm itself.

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.

5 participants