Hi,阿金 ...

通过背景色设置文字颜色

发表: 2019-01-07 分类:

通过背景色设置文字颜色

有这么一个需求,用户设置选择一个主题颜色,计算出背景色和文字颜色.

通过分析需求,需要最简单的实现方案,背景色和主题色,文字为背景色的对比色.
对比色,可以简单的两种,黑或白色,根据背景色的明暗度使用白或黑.

获取色值的明暗度

明暗度,通过两种色彩模式获取.

  1. PS中,HSV(HSB)色彩模式:
    H:色相 (0-360)
    S:饱和度 (0-100%)
    V:亮度 (0-100%)

  2. 在CSS中只支持HSL色彩模式:
    H:色相 (0-360)
    S:饱和度 (0-100%)
    L:明度 (0-100%)

纯红色:RGB(255,0,0)在不同色彩模式的表现.

HSV,为0,100%,100%

HSL,为0,100%,50%

HSl更适合人类眼睛,通过观察我们只需要判断HSl色彩模式的L就可以了.L:50%时,使用明或暗都可以.

使用JS转换色值

因为前端考虑兼容性,CSS常用两种色彩模式,RGB的十进制和十六进制.透明度暂时不考虑.

HEX转RGB

参考公式:__

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var colorRgb = function(sColor){
sColor = sColor.toLowerCase();
//十六进制颜色值的正则表达式
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
// 如果是16进制颜色
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
var sColorNew = "#";
for (var i=1; i<4; i+=1) {
sColorNew += sColor.slice(i, i+1).concat(sColor.slice(i, i+1));
}
sColor = sColorNew;
}
//处理六位的颜色值
var sColorChange = [];
for (var i=1; i<7; i+=2) {
sColorChange.push(parseInt("0x"+sColor.slice(i, i+2)));
}
return "RGB(" + sColorChange.join(",") + ")";
}
return sColor;
};

RGB转HSL

参考网上的公式函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* RGB 颜色值转换为 HSL.
* 转换公式参考自 http://en.wikipedia.org/wiki/HSL_color_space.
* r, g, 和 b 需要在 [0, 255] 范围内
* 返回的 h, s, 和 l 在 [0, 1] 之间
*
* @param Number r 红色色值
* @param Number g 绿色色值
* @param Number b 蓝色色值
* @return Array HSL各值数组
*/
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;

if (max == min){
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}

return [h, s, l];
}

明暗度判断

明暗度是基于人眼的感光程度来的,可以选择一个舒适的取值范围,下面是我的人眼取值.

  1. 通过L值判断,在大于60左右为”亮”.
  2. 直接通过RGB值来判断也可,比值公式

(0.213 rgb[0] + 0.715 rgb[1] + 0.072 * rgb[2]) >255/2

完成

项目中

对色盘认识不够,不然可以取亲合一点的对比色,那就完美了.

我主要用于electron封装壳主题色改变,electron和web是两套系统,只能通过 html中的meta来获取web当前的主题,从而改变标题栏等颜色.

html中:

electron-vue中

mounted():

1
2
3
4
5
6
7
8

// theme
webview.addEventListener('did-change-theme-color', (e,themeColor) => {
if(e.themeColor){
this.theme=e.themeColor
this.changeTheme(e.themeColor);
}
});

method()中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

changeTheme(themeColor){
themeColor=themeColor.toLowerCase();

const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
let rgbColor=[];
// 十六进制转换RGB
if (reg.test(themeColor)) {
if (themeColor.length === 4) {
rgbColor[0]=parseInt("0x"+themeColor.substr(1,1)+themeColor.substr(1,1)+themeColor.substr(1,1));
rgbColor[1]=parseInt("0x"+themeColor.substr(2,1)+themeColor.substr(2,1)+themeColor.substr(2,1));
rgbColor[2]=parseInt("0x"+themeColor.substr(3,1)+themeColor.substr(3,1)+themeColor.substr(3,1));
}else{
rgbColor[0]=parseInt("0x"+themeColor.substr(1,2));
rgbColor[1]=parseInt("0x"+themeColor.substr(2,2));
rgbColor[2]=parseInt("0x"+themeColor.substr(4,2));
}

}else if(/^(rgb|RGB)/.test(themeColor)){
rgbColor = themeColor.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
}

// 获取颜色明暗度
let isLight=false;
if(rgbColor){
let isLightValue =(0.213 * rgbColor[0] +0.715* rgbColor[1] +0.072 * rgbColor[2]);
// 人眼明暗度 0.213,0.715,0.072
isLight=isLightValue >155;
//console.log(themeColor,isLightValue);
}else{
themeColor='#5b6270';
isLight=false;
}


const TextColor=isLight?'#333':'#f5f5f5';
this.themeStyle={
color:TextColor,
background:themeColor
}
}

本文作者:阿金

本文链接:http://www.hi-arkin.com/2019/01/07/Javascript/isLight/

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

Tags: 颜色

扫描二维码,分享此文章