自动更改文本颜色以确保可读性
Automatically change text color to assure readability
用户可以通过接受RGB十六进制表示法的文本框设置按钮的背景颜色:ff00ff
、ccaa22
等。因此,我需要将文本颜色设置为相反的颜色。不确定术语(相反的颜色),但想法是确保可读性。
您可以反转背景色并将其用作前景色。以下算法产生的结果与Photoshop中的"图像>调整>反转"颜色命令相同:
function invertColor(hexTripletColor) {
var color = hexTripletColor;
color = color.substring(1); // remove #
color = parseInt(color, 16); // convert to integer
color = 0xFFFFFF ^ color; // invert three bytes
color = color.toString(16); // convert to hex
color = ("000000" + color).slice(-6); // pad with leading zeros
color = "#" + color; // prepend #
return color;
}
/*
* Demonstration
*/
function randomColor() {
var color;
color = Math.floor(Math.random() * 0x1000000); // integer between 0x0 and 0xFFFFFF
color = color.toString(16); // convert to hex
color = ("000000" + color).slice(-6); // pad with leading zeros
color = "#" + color; // prepend #
return color;
}
$(function() {
$(".demolist li").each(function() {
var c1 = randomColor();
var c2 = invertColor(c1);
$(this).text(c1 + " " + c2).css({
"color": c1,
"background-color": c2
});
});
});
body { font: bold medium monospace; }
.demolist { margin: 0; padding: 0; list-style-type: none; overflow: hidden; }
.demolist li { float: left; width: 5em; height: 5em; text-align: center; }
<ul class="demolist">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
请注意,这不是一个防弹的解决方案。接近50%亮度和/或饱和度的颜色将不会产生足够的对比度。
jsFiddle上的演示
Salaman的代码很好,但有时他的反转不够可读。我使用YCbCr,只是改变灰度。
function invertColor(rgb) {
var yuv = rgb2yuv(rgb);
var factor = 180;
var threshold = 100;
yuv.y = clamp(yuv.y + (yuv.y > threshold ? -factor : factor));
return yuv2rgb(yuv);
}
jsfiddle演示
我在评论中将另一个问题链接到此主题
JS函数来计算补色?
正如Tejasva所说,你需要将RGB转换为HSL,补充色调并将其转换回来。
我将链接的答案作为一个示例来实现。如果这对你有帮助,请投票支持原始海报,因为他们实际上提供了解决方案。
示例
http://jsfiddle.net/pLZ89/2/
我曾经遇到过同样的问题,并在互联网上收集信息,也使用Salman A答案,我想出了这个函数,它支持十六进制、rgb和rgba
var invertColor = function (color) {
var hex = '#';
if(color.indexOf(hex) > -1){
color = color.substring(1);
color = parseInt(color, 16);
color = 0xFFFFFF ^ color;
color = color.toString(16);
color = ("000000" + color).slice(-6);
color = "#" + color;
}else{
color = Array.prototype.join.call(arguments).match(/(-?[0-9'.]+)/g);
for (var i = 0; i < color.length; i++) {
color[i] = (i === 3 ? 1 : 255) - color[i];
}
if(color.length === 4){
color = "rgba("+color[0]+","+color[1]+","+color[2]+","+color[3]+")";
}else{
color = "rgb("+color[0]+","+color[1]+","+color[2]+")";
}
}
return color;
}
但我不认为这是你需要的,我发现了一些更有趣的东西,下面的函数将返回白色或黑色,它将决定一个在给定颜色上更可读。
var getContrastYIQ = function (color){
var hex = '#';
var r,g,b;
if(color.indexOf(hex) > -1){
r = parseInt(color.substr(0,2),16);
g = parseInt(color.substr(2,2),16);
b = parseInt(color.substr(4,2),16);
}else{
color = color.match(/'d+/g);
r = color[0];
g = color[1];
b = color[2];
}
var yiq = ((r*299)+(g*587)+(b*114))/1000;
return (yiq >= 128) ? 'black' : 'white';
}
我不认为这是我的功劳,我只是受到了启发,并根据自己的需求进行了修改。
来源:YIQ函数解释
聚会有点晚,但IMO所有文本都应该是浅色或深色。彩色文本用于链接。
下面是我写的一个coffeescript函数,用来决定使用哪个:
is_light = (hex_color) ->
c = hex_color.replace(/^#/,'')
sum = parseInt(c[0]+c[1], 16)
sum += parseInt(c[2]+c[3], 16)
sum += parseInt(c[4]+c[5], 16)
log "sum is #{sum}"
sum > 382.6
var getContrastYIQ = function(color) {
var hex = '#';
var r, g, b;
if (color.indexOf(hex) > -1) {
r = parseInt(color.substr(1, 2), 16);
g = parseInt(color.substr(3, 2), 16);
b = parseInt(color.substr(5, 2), 16);
} else {
color = color.match(/'d+/g);
r = color[0];
g = color[1];
b = color[2];
}
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
return (yiq >= 128) ? 'black' : 'white';
}
感谢ZetCoy的帖子!必须调整你的"color.substr("数组位置来解释初始的"#";然后它工作得很好!你也可以使用color.replace("#",");在if块中。。。
您可以使用这个简单的模式来实现这个目标。只需将颜色从RGB转换为HSV形式。您可以使用此链接。然后使用这个伪代码;
rr = (color>>16)&0xFF;
gg = (color>>8)&0xFF;
bb = color & 0xFF;
someBrightColor = 0xFFFFFF;
someDarkColor = 0x000000;
hsvColor = rgbToHsv( rr, gg, bb );
//
//hsv is array: [h,s,v]...all values in [0,1]
//
//color is from dark range, if hsv < 0.5, so we need bright color to draw text, because in dark color bright color 'will be more visible'.
if( hsvColor[2] <= 0.5 )
textColor = someBrightColor ;
//this is opposite case , when in more bright color, the dark color 'will be more visible'
else
textColor = someDarkColor ;
也可以将[0,1]范围划分为更多的部分。与其定义2种颜色(someBrightColor,someDarkColor),不如定义更多的颜色。我建议的方法是"背景颜色有多亮,文本颜色必须是深色,反之亦然"。
这里有一个非常小的方法来补充十六进制值//十六进制值,如"aa00cc"
function complementHex(hexValue){
var reqHex = "";
for(var i=0;i<6;i++){
reqHex = reqHex + (15-parseInt(hexValue[i],16)).toString(16);
}
return reqHex;
}
var getContrastYIQ = function(color) {
var hex = '#';
var r, g, b;
if (color.indexOf(hex) > -1) {
r = parseInt(color.substr(1, 2), 16);
g = parseInt(color.substr(3, 2), 16);
b = parseInt(color.substr(5, 2), 16);
} else {
color = color.match(/'d+/g);
r = color[0];
g = color[1];
b = color[2];
}
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
return (yiq >= 128) ? 'black' : 'white';
}
var getContrastYIQ = function(color) {
var hex = '#';
var r, g, b;
if (color.indexOf(hex) > -1) {
r = parseInt(color.substr(1, 2), 16);
g = parseInt(color.substr(3, 2), 16);
b = parseInt(color.substr(5, 2), 16);
} else {
color = color.match(/'d+/g);
r = color[0];
g = color[1];
b = color[2];
}
var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
return (yiq >= 128) ? 'black' : 'white';
}
您希望在开始和结束颜色之间至少保持一些差异。如果你采用相反的颜色,这对中心的rgb值来说就成了一个问题,所以对于这些值来说,采用opsite值是个坏主意,因为对比度会下降,离中间越近(127-128)。因此,这里有一些代码要记住,要始终保持起始数字和结果之间至少有一个设定的差值,如果它不能遵守设定的最小亮度差,则需要0或255,以获得所讨论的r g b值。。。
假设我们有值为{ r: 216, g: 67, b: 130 }
的颜色
下面的函数将返回CCD_ 4作为结果。
如果黑色或白色模式设置为true,它将只返回黑色或白色。
StackBlitz
function getGoodContrastColor(options) {
// check if black or white mode is enabled then check if total brightness values is greater than 255 * 3 / 2, if so, take black, else take white
let r = options.blackOrWhiteMode == true ? options.r + options.g + options.b > 255 * 3 / 2 ? 0 : 255 : null;
let g = options.blackOrWhiteMode == true ? options.r + options.g + options.b > 255 * 3 / 2 ? 0 : 255 : null;
let b = options.blackOrWhiteMode == true ? options.r + options.g + options.b > 255 * 3 / 2 ? 0 : 255 : null;
console.log('rgb values after the first condition', { r, g, b });
// check if the oposite color respects the minimum brightness difference, if so, take that
r = r != null ? r : Math.abs(options.r - (255 - options.r)) >= options.minimumBrightnessDifference ? 255 - options.r : null;
g = g != null ? g : Math.abs(options.g - (255 - options.g)) >= options.minimumBrightnessDifference ? 255 - options.g : null;
b = b != null ? b : Math.abs(options.b - (255 - options.b)) >= options.minimumBrightnessDifference ? 255 - options.b : null;
console.log('rgb values after the second condition', { r, g, b });
// check if the color + minimum brightness difference is smaller or equal to 255, if so, take that
r = r != null ? r : options.r + options.minimumBrightnessDifference <= 255 ? options.r + options.minimumBrightnessDifference : null;
g = g != null ? g : options.g + options.minimumBrightnessDifference <= 255 ? options.g + options.minimumBrightnessDifference : null;
b = b != null ? b : options.b + options.minimumBrightnessDifference <= 255 ? options.b + options.minimumBrightnessDifference : null;
console.log('rgb values after the third condition', { r, g, b });
// check if the color - minimum brightness difference is greater or equal to 0, if so, take that
r = r != null ? r : options.r - options.minimumBrightnessDifference >= 0 ? options.r - options.minimumBrightnessDifference : null;
g = g != null ? g : options.g - options.minimumBrightnessDifference >= 0 ? options.g - options.minimumBrightnessDifference : null;
b = b != null ? b : options.b - options.minimumBrightnessDifference >= 0 ? options.b - options.minimumBrightnessDifference : null;
console.log('rgb values after the fourth condition', { r, g, b });
// check if the color is greater than 127, if so, take 0, else take 255
r = r != null ? r : options.r > 127 ? 0 : 255;
g = g != null ? g : options.g > 127 ? 0 : 255;
b = b != null ? b : options.b > 127 ? 0 : 255;
console.log('rgb values after the fifth condition', { r, g, b });
return { r: r, g: g, b: b };
}
getGoodContrastColor({ r: 216, g: 67, b: 130, minimumBrightnessDifference: 128 });
getGoodContrastColor({ r: 216, g: 67, b: 130, minimumBrightnessDifference: 128, blackOrWhiteMode: true });
- Amd,希望确保某个东西总是最后执行
- 我如何才能确保计时器设置为每天4点半,所以我不会;不用在Javascript中提及某个日期
- gcloud节点-我如何确保通过签名URL上传到谷歌云存储的文件是公开可读的
- 如何确保在AngularJS中,数据在使用之前先加载
- 如何确保JQuery的一行在另一行之前运行
- 如何确保函数/方法参数为certian类型
- 如何确保通过电子邮件发送的html文档中的Google Drive链接不会被识别为附件
- 如何确保变量范围在这个循环中得到维护
- Meteor CollectionFS:在显示之前,请确保图像已上传
- jQuery可读性:在<李>要素
- 有没有一种优雅的方式来告诉esint,以确保我们're没有使用任何ES6语法/函数
- 如何确保在浏览我的plone网站时始终启用浏览器中的javascript
- 构建一个HTML小部件来嵌入付费内容-如何确保与后端的通信安全
- 如何确保只选择了一个h:selectOneRadio按钮
- 如何确保只有您的javascript才能连接到您的Web服务器
- Python Javascript哈希库,以确保JSON对象在传输过程中不会损坏
- 确保Javascript支持多个库(例如Angular 1.5,jQuery 2.2.0,ckEditor 4.x,pd
- Javascript以漂亮的印刷方式格式化var_dump以提高可读性
- 确保 jsavascript 文件未缓存
- 自动更改文本颜色以确保可读性