前言
往往前端工程师在选择文本颜色和背景色上一直很头疼,选择的颜色和背景色比例过小的话就会出现看文字眼花的情况,如:
适合阅读的 色彩对比度比例不小于 4.5:1
适合老年人阅读的 不小于7:1
这里分享一个网站: 色彩对比度检查器 (点击跳转)
下面给大家分享能够生成一对自定义颜色对比度的方法
随机生成一对能自定义颜色对比比例的颜色 javascript代码
//颜色生成
function Generate_contrast_color(strength, min_contrast, max_contrast) {
// 随机一个16位颜色
function getRandomColor() {
let color = Math.floor((Math.random() * 256 * 256 * 256)).toString(16)
while (color.length < 6) {//随机生成的可能只有3-6位字符串
color += Math.floor((Math.random() * 16)).toString(16)
}
return '#' + color;
}
//16进制转RGB
function colorToRGB(type, color) {
let color1, color2, color3;
color = '' + color;
if (typeof color !== 'string') return;
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
if (type == 1) {
return `rgb(${color1},${color2},${color3})`;
} else {
return [color1, color2, color3];
}
}
};
//判断颜色灰度 核心原理:颜色于白色进行对比
//color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
function islight(color) {
function luminance(r, g, b) {
var a = [r, g, b].map(function (v) {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(color) {//返回值范围 1 ~ 21
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
rgb = colorToRGB(2, color);
} else {
rgb = color;
}
var lum1 = luminance(255, 255, 255);
var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
var brightest = Math.max(lum1, lum2);
var darkest = Math.min(lum1, lum2);
return (brightest + 0.05)
/ (darkest + 0.05);
}
if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
//颜色鲜艳
return true
} else {
//颜色暗淡
return false
}
};
// 生成对比色
function lightColor(sColor, iStep) {
var asHex = new Array(16);
var haxString = '0123456789abcdef';
for (var i = 0; i < 16; i++) {
asHex[i] = haxString.substr(i, 1);
}
var sRslt = "#";
var iTemp;
for (var i = 1; i < 7; i++) {
iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
if (iTemp > 15)
iTemp = 15;
if (iTemp < 0)
iTemp = 0;
sRslt += asHex[iTemp];
}
return sRslt;
}
//将颜色按照暗亮自动前往对比
function autolightColor(color, istep) {
if (!islight(color)) {
//暗色
return lightColor(color, istep);
} else {
//亮色
return lightColor(color, -istep)
}
}
//计算两色的对比度比例
//colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
//colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
function getContrastRatio(colorA, colorB) {
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
colorA = colorToRGB(2, colorA);
}
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
colorB = colorToRGB(2, colorB);
}
function getLuminanace(values) {
var rgb = values.map((v) => {
var val = v / 255;
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
});
return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
};
var lumA = getLuminanace(colorA);
var lumB = getLuminanace(colorB);
var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
return calculation.toFixed(2);
};
//随机一对
let i = 0;
do {//不是任意一对颜色都是有合适的对比率的,又时初始颜色偏激,但范围有限会导致对出来的颜色对比度不合格
i++;
var color = getRandomColor();
var ContrastColor = autolightColor(color, strength);
var ContrastRatio = getContrastRatio(color, ContrastColor);
if (min_contrast < ContrastRatio && ContrastRatio < max_contrast) {
return [color, ContrastColor, ContrastRatio]
}
} while (i < 10000)//阀门
console.log('经循环10000次,没有合适的一对,返回白色和黑色');
return ['#fff', '#000', 21]
}
//Generate_contrast_color(strength, min_contrast, max_contrast)
//strength = 两色偏移强度; 范围0 ~ 20 ;必须整数
//min_contrast = 最小对比度比例; 范围1 ~ 21
//max_contrast = 最大对比度比例; 范围1 ~ 21
/*--最后生成的颜色对比度比例在 最小对比度比例 和 最大对比度比例 之间。错误返回白色和黑色--*/
/*
返回值:
["#b0b6ce","#404057","5.01"]
[ 颜色1 , 颜色2 , 两色对比比例 ]
*/
var color = Generate_contrast_color(7, 4.5, 21);
var color1 = color[0];
var color2 = color[1];
var ContrastRatio = color[2];
其余便是分支:
如果需要将16位颜色转换成rgb可以这样:
//16进制转RGB
function colorToRGB(color) {
let color1, color2, color3;
color = '' + color;
if (typeof color !== 'string') return;
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
return `rgb(${color1},${color2},${color3})`;
}
};
颜色偏移:
//颜色偏移
//sColor 16位哈希颜色 如:#99cf42
//iStep 偏移力度 0 ~ 20
function lightColor(sColor, iStep) {
var asHex = new Array(16);
var haxString = '0123456789abcdef';
for (var i = 0; i < 16; i++) {
asHex[i] = haxString.substr(i, 1);
}
var sRslt = "#";
var iTemp;
for (var i = 1; i < 7; i++) {
iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
if (iTemp > 15)
iTemp = 15;
if (iTemp < 0)
iTemp = 0;
sRslt += asHex[iTemp];
}
return sRslt;
}
计算两个颜色的对比度比例:
//16进制转RGB
function colorToRGB(type, color) {
let color1, color2, color3;
color = '' + color;
if (typeof color !== 'string') return;
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
if (type == 1) {
return `rgb(${color1},${color2},${color3})`;
} else {
return [color1, color2, color3];
}
}
};
//计算两色的对比度比例
//colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
//colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
function getContrastRatio(colorA, colorB) {
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
colorA = colorToRGB(2, colorA);
}
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
colorB = colorToRGB(2, colorB);
}
function getLuminanace(values) {
var rgb = values.map((v) => {
var val = v / 255;
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
});
return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
};
var lumA = getLuminanace(colorA);
var lumB = getLuminanace(colorB);
var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
return calculation.toFixed(2);
};
判断颜色是否鲜艳
//16进制转RGB
function colorToRGB(type, color) {
let color1, color2, color3;
color = '' + color;
if (typeof color !== 'string') return;
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
if (type == 1) {
return `rgb(${color1},${color2},${color3})`;
} else {
return [color1, color2, color3];
}
}
};
//判断颜色灰度 核心原理:颜色于白色进行对比
//color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
function islight(color) {
function luminance(r, g, b) {
var a = [r, g, b].map(function (v) {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(color) {//返回值范围 1 ~ 21
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
rgb = colorToRGB(2, color);
} else {
rgb = color;
}
var lum1 = luminance(255, 255, 255);
var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
var brightest = Math.max(lum1, lum2);
var darkest = Math.min(lum1, lum2);
return (brightest + 0.05)
/ (darkest + 0.05);
}
if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
//颜色鲜艳
return true
} else {
//颜色暗淡
return false
}
};
html演示:
<!DOCTYPE html>
<html lang="zh_cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机一对合适的颜色,对比度比例可控,演示随机100个</title>
</head>
<body>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
//颜色生成
function Generate_contrast_color(strength, min_contrast, max_contrast) {
// 随机一个16位颜色
function getRandomColor() {
let color = Math.floor((Math.random() * 256 * 256 * 256)).toString(16)
while (color.length < 6) {//随机生成的可能只有3-6位字符串
color += Math.floor((Math.random() * 16)).toString(16)
}
return '#' + color;
}
//16进制转RGB
function colorToRGB(type, color) {
let color1, color2, color3;
color = '' + color;
if (typeof color !== 'string') return;
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length == 3) {
color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
}
if (/^[0-9a-fA-F]{6}$/.test(color)) {
color1 = parseInt(color.substr(0, 2), 16);
color2 = parseInt(color.substr(2, 2), 16);
color3 = parseInt(color.substr(4, 2), 16);
if (type == 1) {
return `rgb(${color1},${color2},${color3})`;
} else {
return [color1, color2, color3];
}
}
};
//判断颜色灰度 核心原理:颜色于白色进行对比
//color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
function islight(color) {
function luminance(r, g, b) {
var a = [r, g, b].map(function (v) {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(color) {//返回值范围 1 ~ 21
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
rgb = colorToRGB(2, color);
} else {
rgb = color;
}
var lum1 = luminance(255, 255, 255);
var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
var brightest = Math.max(lum1, lum2);
var darkest = Math.min(lum1, lum2);
return (brightest + 0.05)
/ (darkest + 0.05);
}
if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
//颜色鲜艳
return true
} else {
//颜色暗淡
return false
}
};
// 生成对比色
function lightColor(sColor, iStep) {
var asHex = new Array(16);
var haxString = '0123456789abcdef';
for (var i = 0; i < 16; i++) {
asHex[i] = haxString.substr(i, 1);
}
var sRslt = "#";
var iTemp;
for (var i = 1; i < 7; i++) {
iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
if (iTemp > 15)
iTemp = 15;
if (iTemp < 0)
iTemp = 0;
sRslt += asHex[iTemp];
}
return sRslt;
}
//将颜色按照暗亮自动前往对比
function autolightColor(color, istep) {
if (!islight(color)) {
//暗色
return lightColor(color, istep);
} else {
//亮色
return lightColor(color, -istep)
}
}
//计算两色的对比度比例
//colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
//colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
function getContrastRatio(colorA, colorB) {
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
colorA = colorToRGB(2, colorA);
}
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
colorB = colorToRGB(2, colorB);
}
function getLuminanace(values) {
var rgb = values.map((v) => {
var val = v / 255;
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
});
return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
};
var lumA = getLuminanace(colorA);
var lumB = getLuminanace(colorB);
var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
return calculation.toFixed(2);
};
//随机一对
let i = 0;
do {//不是任意一对颜色都是有合适的对比率的,又时初始颜色偏激,但范围有限会导致对出来的颜色对比度不合格
i++;
var color = getRandomColor();
var ContrastColor = autolightColor(color, strength);
var ContrastRatio = getContrastRatio(color, ContrastColor);
if (min_contrast < ContrastRatio && ContrastRatio < max_contrast) {
return [color, ContrastColor, ContrastRatio]
}
} while (i < 10000)//阀门
console.log('经循环10000次,没有合适的一对,返回白色和黑色');
return ['#fff', '#000', 21]
}
//Generate_contrast_color(strength, min_contrast, max_contrast)
//strength = 两色偏移强度; 范围0 ~ 20 ;必须整数
//min_contrast = 最小对比度比例; 范围1 ~ 21
//max_contrast = 最大对比度比例; 范围1 ~ 21
/*--最后生成的颜色对比度比例在 最小对比度比例 和 最大对比度比例 之间。错误返回白色和黑色--*/
/*
返回值:
["#b0b6ce","#404057","5.01"]
[ 颜色1 , 颜色2 , 两色对比比例 ]
*/
var color = Generate_contrast_color(7, 4.5, 21);
var color1 = color[0];
var color2 = color[1];
var ContrastRatio = color[2];
/*----------------------下面为演示代码---------------------*/
function setStyle(el, styles) {
for (var key in styles) {
el.style[key] = styles[key];
}
}
for (let index = 0; index < 100; index++) {
div = document.createElement('div');
div.id = index;
document.body.appendChild(div);
var color = Generate_contrast_color(7, 4.5, 21);
var color1 = color[0];
var color2 = color[1];
var ContrastRatio = color[2];
var span = document.createElement("span");
span.innerText = "文本文字";
setStyle(span, {
display: 'inline-block',
padding: '10px',
margin: '30px',
textAlign: 'center',
color: color1,
'background-color': color2
});
document.getElementById(index).appendChild(span);
span = document.createElement("span");
var text = " 文字颜色:" + color1 + ' 背景颜色:' + color2 + '; 对比率:' + ContrastRatio;
span.innerText = text;
document.getElementById(index).appendChild(span);
}
</script>
</body>
</html>
创造不易,麻烦转载留个言
评论 (0)