Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate color range for 1 color, from light color to dark(er) color

I found this nice color palette enter image description here

I want to use it to let the user select a color palette being the first 8 colors (vertically) from this palette . So I thought I could add some more, and of course not type all the hex codes.

Is there a way to calculate these values?

So for instance enter color c6ff89 (or any other color) and then end with 498e00 (which is the right column).

So the underlying question is: is there math to do on these colors?

And second, now that I am looking at these colors: the items on the top row all seem the same kind of 'lightness' (don't know what term to use). What I mean the left one is the same light of blue as the right is light of green, so the same lightness (/darkness). Is that also possible to calculate, to calculate the same kind of lightness for let's say red or orange?

like image 741
Michel Avatar asked Dec 22 '22 16:12

Michel


1 Answers

Yes, and it is actually pretty simple to calculate them!

In hsl these are just colors with full saturation and a lightness that decreases 7% each step:

#c6ff89 is hsl(89deg 100% 77%),
#b5ff65 is hsl(89deg 100% 70%);
#a3ff42 is hsl(89deg 100% 63%);
...
#498e00 is hsl(89deg 100% 28%);

To get the other color gradients you just need to change the hue.

Here's a snippet to try it out.

 function colorChanged(h) {

    let s = 100;
    let l = 77;

    document.getElementById('deg').innerText = h;

    for (let color of document.getElementsByClassName('color')) {

        color.style.backgroundColor = `hsl(${h}deg ${s}% ${l}%)`;
        color.innerText = HSLToRGB(h, s, l);

        l -= 7;
    }
}

function HSLToRGB(h, s, l) {
    s /= 100;
    l /= 100;

    let c = (1 - Math.abs(2 * l - 1)) * s,
        x = c * (1 - Math.abs((h / 60) % 2 - 1)),
        m = l - c / 2,
        r = 0,
        g = 0,
        b = 0;

    if (0 <= h && h < 60) {
        r = c; g = x; b = 0;
    } else if (60 <= h && h < 120) {
        r = x; g = c; b = 0;
    } else if (120 <= h && h < 180) {
        r = 0; g = c; b = x;
    } else if (180 <= h && h < 240) {
        r = 0; g = x; b = c;
    } else if (240 <= h && h < 300) {
        r = x; g = 0; b = c;
    } else if (300 <= h && h < 360) {
        r = c; g = 0; b = x;
    }

    return "#" + 
      Math.floor((r + m) * 255).toString(16).padStart(2, '0') + 
      Math.floor((g + m) * 255).toString(16).padStart(2, '0') + 
      Math.floor((b + m) * 255).toString(16).padStart(2, '0');
}

colorChanged(89);
.color {
    width: 200px;
    height: 45px;
    background: black;
    margin-bottom: 8px;

    display: flex;
    align-items: center;
    justify-content: center;
}
<html>
<body>
    <label>
        <input type="range" min="0" max="360" value="89" onchange="colorChanged(this.value)" />
        <span id="deg"></span>deg
    </label>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
    <div class="color"></div>
</body>

</html>

color conversion stolen from here: https://css-tricks.com/converting-color-spaces-in-javascript/

like image 173
Roald Avatar answered May 15 '23 15:05

Roald