How to convert this text contrast function to version for hsl values

23 Views Asked by At

I needed a function that takes a color as input which is a background color for text. Based on that given color, the function should return the color white or black that can be used as the text color for the best contrast.

I once copied the function below from the internet and it works great for a hex color string as input. Now the requirements have changed, and I want to convert this function for an input value in hsl. The input should not be a string of a color format anymore, but just the hsl values, like: getContrastTextColor(h, s, l).

It seems to be simple but I don't know how to do this. The problem is not Javascript, but the logic.

function getContrastTextColor(hex)
{
    /*
    From this W3C document: http://www.webmasterworld.com/r.cgi?f=88&d=9769&url=http://www.w3.org/TR/AERT#color-contrast

    Color brightness is determined by the following formula: 
    ((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
    */

    const threshold = 130; /* about half of 256. Lower threshold equals more dark text on dark background  */

    const hRed = hexToR(hex);
    const hGreen = hexToG(hex);
    const hBlue = hexToB(hex);


    function hexToR(h) { return parseInt((cutHex(h)).substring(0, 2), 16) }
    function hexToG(h) { return parseInt((cutHex(h)).substring(2, 4), 16) }
    function hexToB(h) { return parseInt((cutHex(h)).substring(4, 6), 16) }
    function cutHex(h) { return (h.charAt(0) == "#") ? h.substring(1, 7) : h }

    const cBrightness = ((hRed * 299) + (hGreen * 587) + (hBlue * 114)) / 1000;
    if (cBrightness > threshold) { return "#000000"; } else { return "#ffffff"; }
}
1

There are 1 best solutions below

0
Shariar Hasan On

Well, there is a previous answer on that, You can see the code here.

just convert the hsl into hex.

function hslToHex(h, s, l) {
  l /= 100;
  const a = s * Math.min(l, 1 - l) / 100;
  const f = n => {
    const k = (n + h / 30) % 12;
    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
    return Math.round(255 * color).toString(16).padStart(2, '0');   // convert to Hex and prefix "0" if needed
  };
  return `#${f(0)}${f(8)}${f(4)}`;
}

then get the hex value, and then use your previous code.

const hex = hslToHex(h, s, l)
/* rest of the code . . . */