在javascript中计算对比色

时间:2009-03-11 15:23:18

标签: javascript color-scheme

在我们正在处理的一个页面上,用户可以更改显示文本的背景。

我们希望自动更改前景色以保持文本的合理对比度。

我们也希望颜色范围是自由裁量的。例如,如果背景以255为增量从白色变为黑色,我们不希望看到255种前景色调。在这种情况下,可能是2到4,只是为了维持合理的对比度。

任何UI /设计/颜色专家/画家都在制作公式?

5 个答案:

答案 0 :(得分:22)

根据luma做出的黑白决定非常适合我。 Luma是R,G和B值的加权和,根据人类对相对亮度的感知进行调整,在视频应用中显然很常见。 luma的官方定义随着时间的推移而发生了变化,具有不同的权重;见这里:http://en.wikipedia.org/wiki/Luma_(video)。我使用Rec获得了最好的结果。 709版本,如下面的代码所示。可能165的黑白阈值似乎很好。

function contrastingColor(color)
{
    return (luma(color) >= 165) ? '000' : 'fff';
}
function luma(color) // color can be a hx string or an array of RGB values 0-255
{
    var rgb = (typeof color === 'string') ? hexToRGBArray(color) : color;
    return (0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]); // SMPTE C, Rec. 709 weightings
}
function hexToRGBArray(color)
{
    if (color.length === 3)
        color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2);
    else if (color.length !== 6)
        throw('Invalid hex color: ' + color);
    var rgb = [];
    for (var i = 0; i <= 2; i++)
        rgb[i] = parseInt(color.substr(i * 2, 2), 16);
    return rgb;
}

答案 1 :(得分:12)

就纯粹的可读性而言,您希望在任何背景上使用黑白文本。因此,将RGB转换为HSV,并检查V是否为&lt; 0.5。如果是这样,白色,如果不是,黑色。

首先尝试一下,看看你是否觉得它很有吸引力。

如果你不这样做,那么你可能希望当你的背景太亮或太暗时,白色和黑色不会那么明显。要将其调低,请保持相同的色调和饱和度,并将这些值用于亮度:

background V  foreground V
0.0-0.25      0.75
0.25-0.5      1.0
0.5-0.75      0.0
0.75-1.0      0.25

在中等颜色上,您仍会看到黑色或白色文字,这些文字非常易读。在深色或浅色上,您将看到相同的颜色文本,但在亮度方面至少3/4,因此仍然可读。我希望它看起来不错:))

答案 2 :(得分:7)

尝试this example,根据r,g和b值的平均值,将其设置为黑色或白色。也适合测试!如果您发现不能很好地工作的情况,请在那里替换更好的算法。

<html> 
<head> 
<script> 
function rgbstringToTriplet(rgbstring)
{
    var commadelim = rgbstring.substring(4,rgbstring.length-1);
var strings = commadelim.split(",");
var numeric = [];
for(var i=0; i<3; i++) { numeric[i] = parseInt(strings[i]); }
return numeric;
}

function adjustColour(someelement)
{
   var rgbstring = someelement.style.backgroundColor;
   var triplet = rgbstringToTriplet(rgbstring);
   var newtriplet = [];
   // black or white:
   var total = 0; for (var i=0; i<triplet.length; i++) { total += triplet[i]; } 
   if(total > (3*256/2)) {
     newtriplet = [0,0,0];
   } else {
 newtriplet = [255,255,255];
   }
   var newstring = "rgb("+newtriplet.join(",")+")";
   someelement.style.color = newstring;
   return true;
}

function randomiseBackground(someelement)
{
 var vals = [];
 for(var i=0; i<3; i++) { vals[i]=Math.floor(Math.random()*256+1); }
 someelement.style.backgroundColor="rgb("+vals.join(",")+")";
 return true;
}
</script> 
</head> 
<body onload="adjustColour(document.getElementById('mypara'));"> 
<p id="mypara" style="background-color:#2287ea">Some text</p> 
<form> 
    <input type=button onclick="var elem=document.getElementById('mypara'); randomiseBackground(elem); adjustColour(elem);" value="randomise background" /> 
</form> 
</body> 
</html>

答案 3 :(得分:1)

你可能想要改变色调,但不是饱和度或值。

因此,将您的RGB值转换为HSV,向H添加180度(当然模数为360度),然后转换回RGB。

Conversion forumlas are here

答案 4 :(得分:0)

由于javascript处理十进制值的方式,它实现起来有点复杂。 为此,我发现让背景改变任何颜色要好得多,但文字只是在黑白之间切换。 如果你使用对比色,很多组合将很难站立。还要注意有些人是色盲,所以从可访问性的角度来看,这不是一个好主意。