const hexToRGB = (hex) => {
/* Convert an RGB value (eg. #FFFFFF) into it's rgb triplet expressed as
* floating points.
* */
// Strip the leading # from the hex code
hex = hex.replace(/^#?([0-9a-f]{6})$/i, '$1')
// Convert the hex into a number
hex = Number(`0x${hex}`)
// Simple bit shifting to slice off each component from the hex map
return {
r: parseFloat(hex >> 16 & 0xff) / 255.0,
g: parseFloat(hex >> 8 & 0xff) / 255.0,
b: parseFloat(hex & 0xff) / 255.0
}
}
const sRGBTransform = (c) => {
/* Convert an sRGB to the correct color space in order to compute luminance formula.
* c is the color as float.
* */
if (c <= 0.03928) {
return c/12.92
}
return Math.pow(c+0.055/1.055, 2.4)
}
const getLuminance = ({r, g, b}) => {
/*
* Returns the luminance of an RGB triplet. Expects the r,g,b values to be
* already floating point numbers in the range of 0-1.
* */
return 0.2126 * sRGBTransform(r) + 0.7152 * sRGBTransform(g) + 0.0722 * sRGBTransform(b)
}
const contrastRatio = (a, b) => {
/*
* Calculate contrast ratio as per WCAG 2.0
* https://www.w3.org/TR/WCAG20-TECHS/G17.html
* the lighter color is l1, the darker is l2
*
* a and b are luminance values for the two colors
* */
l1 = b
l2 = a
if (a > b) {
l1 = a
l2 = b
}
return (l1 + 0.05) / (l2 + 0.05)
}
const pickTextColor = (color, darkColor, lightColor) => {
/* Returns the value of the prefered color between darkColor and lightColor
* to maximise the contrast against the color.
* Colors are expressed in thier RGB values as a hex string (eg. #FFCCDD).
* Returns the hex string of the chosen color between dark and light.
* */
let darkLum = getLuminance(hexToRGB(darkColor))
let lightLum = getLuminance(hexToRGB(lightColor))
let colorLum = getLuminance(hexToRGB(color))
const darkContrast = contrastRatio(colorLum, darkLum)
const lightContrast = contrastRatio(colorLum, lightLum)
if (contrastRatio(colorLum, darkLum) > contrastRatio(colorLum, lightLum)) {
return darkColor
}
return lightColor
}
let colors = {
white:"#ffffff",
black: "#000000",
ooniblue: "#0588cb",
gray1: "#f1f3f5",
violet5: "#845ef7",
lime9: "#5c940d",
cyan9: "#0b7285"
}
let whiteLum = getLuminance(hexToRGB(colors.white))
let blackLum = getLuminance(hexToRGB(colors.black))
let ooniblueLum = getLuminance(hexToRGB(colors.ooniblue))
console.log(`Luminance of ${colors.white}: ${whiteLum}`)
console.log(`Luminance of ${colors.black}: ${blackLum}`)
console.log(`Luminance of ${colors.ooniblue}: ${ooniblueLum}`)
Object.keys(colors).forEach((name) => {
let chosen = pickTextColor(colors[name], colors.black, colors.white)
console.log(`${name} (${colors[name]}): ${chosen}`)
})
Dark or Light color picker based on luminace
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.