Repository navigation
fix: round Hex4/Hex8 alpha with ALPHA_PRECISION, not a hardcoded 2 - #159
Closed
afonsojanu wants to merge 1 commit into
Closed
afonsojanu wants to merge 1 commit into
afonsojanu wants to merge 1 commit into
Conversation
parseHex rounded the alpha channel of Hex4/Hex8 colors to 2 decimal
places while every other color model (rgb, hsl, hsv, hwb, lab, lch,
cmyk, xyz) rounds alpha to ALPHA_PRECISION (3), a constant that was
raised from 2 to 3 specifically because 2 digits weren't accurate
enough. hex.ts kept the old hardcoded value.
Since a channel only has 256 possible values, this makes 155 of the
256 possible alpha bytes fail to round-trip through a string format:
colord("#cc88").toRgbString() // "rgba(204, 204, 136, 0.53)"
colord("rgba(204, 204, 136, 0.53)").toHex() // "#cccc8887", not ...88
Rounding to 3 digits instead makes every one of the 256 alpha bytes
round-trip exactly (verified by brute force), matching the precision
used by every other color model in the library.
This is an intentional behavior change: parsing "#xxxxxxYY" now
resolves alpha to 3 decimal digits instead of 2 (e.g. 0x80 -> 0.502
instead of 0.5). Hex output (toHex()) and RGB byte values are
unaffected; only the decimal alpha exposed by toRgb()/toRgbString()
and downstream conversions (lab, lch, cmyk, hwb) gains a digit for
alpha bytes that weren't exactly representable at 2 digits.
Fixes #97.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
parseHexrounded the alpha channel of Hex4/Hex8 colors to 2 decimal places, while every other color model in the library (rgb, hsl, hsv, hwb, lab, lch, cmyk, xyz) rounds alpha toALPHA_PRECISION(3). That constant was bumped from 2 to 3 a while back specifically because 2 digits weren't accurate enough (see the comment on it inconstants.ts), buthex.tsstill had the old value hardcoded in two places.Since an alpha byte only has 256 possible values, I checked how many of them survive a round trip through a decimal string at each precision:
ALPHA_PRECISION): 0 out of 256 failConcretely, this is issue #97:
Fix
Both places in
parseHex(Hex4 and Hex8) now round withALPHA_PRECISIONinstead of a hardcoded2, matching every other color model.Behavior change (called out per AGENTS.md)
This is a deliberate behavior change: parsing a Hex4/Hex8 string now resolves alpha to 3 decimal digits instead of 2 (e.g.
#80->0.502instead of0.5).toHex()output and the rounded RGB byte values are unchanged; only the decimal alpha exposed bytoRgb()/toRgbString()and anything derived from it (lab/lch/cmyk/hwb conversions) gains a digit for alpha bytes that weren't exactly representable at 2 digits. I updated the existing test expectations affected by this (a handful of#...80/#...ed-style fixtures intests/colord.test.tsandtests/plugins.test.ts) and added a dedicated round-trip regression test covering all 256 alpha bytes for both Hex4 and Hex8.Testing
npm run lint,npm run check-types,npm run test(103/103 passing, 100% line coverage),npm run sizeall pass locally.tests/colord.test.ts: "Round-trips every Hex4/Hex8 alpha byte through RGB without drift".Closes #97.