You have to extract the three RGB components individually, and then use a standard formula to convert the resulting RGB values into their perceived brightness.
Assuming a six character colour:
var c = c.substring(1); // strip #
var rgb = parseInt(c, 16); // convert rrggbb to decimal
var r = (rgb >> 16) & 0xff; // extract red
var g = (rgb >> 8) & 0xff; // extract green
var b = (rgb >> 0) & 0xff; // extract blue
var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
if (luma < 40) {
// pick a different colour
}
EDIT
Since May 2014 tinycolor
now has a getBrightness()
function, albeit using the CCIR601 weighting factors instead of the ITU-R ones above.
EDIT
The resulting luma value range is 0..255, where 0 is the darkest and 255 is the lightest. Values greater than 128 are considered light by tinycolor
. (shamelessly copied from the comments by @pau.moreno and @Alnitak)
I found this WooCommerce Wordpress PHP function (wc_hex_is_light) and I converted to JavaScript. Works fine!
function wc_hex_is_light(color) {
const hex = color.replace('#', '');
const c_r = parseInt(hex.substr(0, 2), 16);
const c_g = parseInt(hex.substr(2, 2), 16);
const c_b = parseInt(hex.substr(4, 2), 16);
const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
return brightness > 155;
}
The TinyColor library (you've already mentioned it) provides several functions for inspecting and manipulating colors, among them:
getBrightness
Returns the perceived brightness of a color, from 0-255, as defined by Web Content Accessibility Guidelines (Version 1.0).
tinycolor("#fff").getBrightness(); // 255
isLight
Return a boolean indicating whether the color's perceived brightness is light.
tinycolor("#fff").isLight(); // true tinycolor("#000").isLight(); // false
isDark
Return a boolean indicating whether the color's perceived brightness is dark.
tinycolor("#fff").isDark(); // false tinycolor("#000").isDark(); // true
getLuminance
Returns the perceived luminance of a color, from 0-1 as defined by Web Content Accessibility Guidelines (Version 2.0).
tinycolor("#fff").getLuminance(); // 1
You can compute the luminance:
Luminance is thus an indicator of how bright the surface will appear.
So it's great to choose if the text should be white or black.
var getRGB = function(b){
var a;
if(b&&b.constructor==Array&&b.length==3)return b;
if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(a[1]),parseInt(a[2]),parseInt(a[3])];
if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];
if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],
16)];
if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];
return (typeof (colors) != "undefined")?colors[jQuery.trim(b).toLowerCase()]:null
};
var luminance_get = function(color) {
var rgb = getRGB(color);
if (!rgb) return null;
return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
}
The method above allows you to pass the color in different formats, but the algorithm is basically just in luminance_get
.
When I used it, I was setting the color to black if the luminance was greater than 180
, white otherwise.
This work with hex e.g #fefefe
function isTooDark(hexcolor){
var r = parseInt(hexcolor.substr(1,2),16);
var g = parseInt(hexcolor.substr(3,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
// Return new color if to dark, else return the original
return (yiq < 40) ? '#2980b9' : hexcolor;
}
You can change it to return true
or false
by change
return (yiq < 40) ? '#2980b9' : hexcolor;
to
return (yiq < 40);
There's an important distinction here between luminance and brightness. Luminance, at the end of the day, is a measure of how much energy travels through a certain area and completely ignores how our perceptual systems perceive that energy. Brightness, on the other hand, is a measure of how we perceive that energy and takes into the account the relationship between luminance and our perceptual system. (As a point of confusion, there is a term called relative luminance, which seems to be used synonymously with brightness terms. It tripped me up good).
To be precise, you are looking for "brightness" or "value" or "relatively luminance" as others have suggested. You can calculate this in several different way (such is to be human!) http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With