背景
产品:有一个需求,根据返回数据生成带背景色的色块,数据会很多,颜色随机生成并且不能重复,然后色块上的数字要看的清楚,要求文字颜色和背景色不能接近,应该不难吧...
我:“xxxxxxxxx”
好吧,能咋办呢,面向领导开发,打工人只能硬着头皮开(百)发(度)呗,吐槽一下,有些pm是产品经理,有些pm只是个画原型和传达需求的。
思路
我们平常使用的颜色无非就是通过 红色(R)、绿色(G)和蓝色(B)三个维度随机混合成不同的颜色,所以通过随机数,来生成16进制的颜色
代码实现
tips:通过亮度的差异对比,0.5是一个经验值,它代表了人眼的对比度敏感度,根据人类视觉的生理特点,相对亮度介于0.45到0.65之间的颜色,对于黑白对比度的敏感度较高,容易产生视觉渐近效应,因此0.5是一个相对缓和的中间值,适用于大多数场景。(相关资料查阅)
具体来说,如果颜色的相对亮度luminance
大于0.5,则说明颜色比较浅,本身已经趋于白色,此时使用黑色作为前景色能够更好地提高视觉对比度,保证文本的易读性。如果颜色的相对亮度小于等于0.5,则说明颜色比较深,本身已经趋于黑色,此时使用白色作为前景色能够更好地提高视觉对比度
完整代码
function generateColors(numColors) {
let colors = [];
while (colors.length < numColors) {
const color = generateRandomColor(); // 生成随机颜色
if (!colors.includes(color)) {
const luminance = calculateColorLuminance(color); // 计算颜色的相对亮度
const labelColor = (luminance > 0.5) ? '#000000' : '#FFFFFF'; // 根据相对亮度自适应前景色
colors.push({background: color, labelColor: labelColor});
}
}
return colors;
}
function generateRandomColor() {
// letters 是一个包含16个元素的字符串,用于生成16进制的颜色代码
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function calculateColorLuminance(color) {
color = color.substr(1);
const rgb = parseInt(color, 16);
const r = (rgb >> 16) & 0xff; // red
const g = (rgb >> 8) & 0xff; // green
const b = (rgb >> 0) & 0xff; // blue
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
return luminance / 255;
}
calculateColorLuminance
,用于计算颜色的相对亮度,然后通过比较相对亮度来自适应选择字体颜色。(按照WCAG2.0标准进行计算,将颜色的RGB值转换为相对亮度值(0~1.0),最终返回相对亮度值)
const colors = generateColors(100); // 生成100种随机颜色
console.log(colors);
{
background: '#FFFF00',
labelColor: '#000000'
}
最后
通过上面的方案最终完美的交差,通过相关资料的查询也学到了蛮多。补充一句,上面一些思路和代码都是通过openAI生成的,对ai智能发自肺腑的感叹!(cv工程师以后可能也难做了)