Skip to content

Instantly share code, notes, and snippets.

@boronine
Created October 6, 2012 12:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boronine/3844817 to your computer and use it in GitHub Desktop.
Save boronine/3844817 to your computer and use it in GitHub Desktop.
# For a given Lightness, Hue, RGB channel, and limit (1 or 0),
# return Chroma, such that passing this chroma value will cause the
# given channel to pass the given limit.
maxChroma = (L, H) ->
hrad = H / 360 * 2 * Math.PI
sinH = Math.sin hrad
cosH = Math.cos hrad
sub1 = Math.pow(L + 16, 3) / 1560896
sub2 = if sub1 > 0.008856 then sub1 else L / 903.3
(channel) ->
[m1, m2, m3] = m[channel]
top = (0.99915 * m1 + 1.05122 * m2 + 1.14460 * m3) * sub2
rbottom = 0.86330 * m3 - 0.17266 * m2
lbottom = 0.12949 * m3 - 0.38848 * m1
bottom = (rbottom * sinH + lbottom * cosH) * sub2
(limit) ->
# This is the C value that you can put together with the given L and H
# to produce a color that with <RGB channel> = 1 or 2. This means that if C
# goes any higher, the color will step outside of the RGB gamut.
L * (top - 1.05122 * limit) / (bottom + 0.17266 * sinH * limit)
# Used for rgb <-> xyz conversions
m =
R: [3.2406, -1.5372, -0.4986]
G: [-0.9689, 1.8758, 0.0415]
B: [0.0557, -0.2040, 1.0570]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment