JavaScript
计算颜色的相对亮度,并确定相应的颜色
一、需求内容
需求点:给出一组颜色列表,渲染对应的颜色以及颜色值,但是要保证文本颜色和背景色不冲突,文本颜色保持 black
和 white
两种即可
示例如下:每个模块背景色为当前颜色,文案内容为当前颜色值,文案颜色为当前颜色通过计算后的 'black' 或 'white'
二、实现方案
思路
- 背景颜色与文本颜色不能冲突,亮的背景色展示黑色文案,深的背景色展示白色文案
- 使用 YUV 与 RGB 颜色转化公式
- 判断 a 的值,也就是透明度,透明度越小颜色越浅
实现流程
- 先把颜色转化成 rgba
- 根据计算公式 (r * 299 + g * 587 + b * 114) / 1000 将RGB颜色转换为YUV颜色
- 判断计算出来的值在判断 a 的值来确定文本颜色的值
三、代码实现
/** * 把十六进制颜色值转成 rgba 颜色值 * @param {string} hex * @returns {string} rgba 颜色值 */ const hexToRgba = (hex: string): string => { const rgba = [] hex = hex.replace('#', '').padEnd(8, 'F') for (let i = 0; i < hex.length; i+=2) { rgba.push(parseInt(hex.slice(i, i+2), 16)) } return rgba.reduce((prev, item, index) => { return prev += index >= rgba.length - 1 ? Number((item / 255).toFixed(2)) : `${item}, ` }, 'rgba(') + ')' } /** * 计算文本颜色值 * @param {string} hexColor * @returns {'black' | 'white'} 文本颜色值 */ const determineTextColor = (hexColor: string): 'black' | 'white' => { // 将十六进制颜色值转换为 RGB 格式 const rgbColor = hexToRgba(hexColor); // 获取颜色的 RGB 分量 const [r, g, b, a] = (rgbColor.match(/\d+(\.\d+)?/g) || []).map(Number); // 计算颜色的相对亮度 const brightness = (r * 299 + g * 587 + b * 114) / 1000; // 根据相对亮度确定文本颜色 return brightness > 125 ? 'black' : (a < 0.4 ? 'black' : 'white') }
四、案例效果展示
案例
const colorList = [ "#FAFAFAA6", "#000000FF", "#000000EE", "#000000AA", "#00000088", "#00000066", "#00000033", "#00000022", "#00000011", "#00000000", "#333333FF", "#FFFFFFFF", "#FFFFFFEE", "#FFFFFFBB", "#FFFFFFAA", "#FFFFFF99", "#FFFFFF88", "#FFFFFF66", "#FFFFFF33", "#FFFFFF22", "#FFFFFF11", "#344258FF", "#4CAF50DE", "#364FBBFF", "#00000040", "#FF4D4FFF", "#233494FF", "#0505050F", "#00000005", "#E7E8EAFF", "#F5F7FAFF", "#7A7A7AFF", "#1677FFFF", "#69B1FFFF", "#0958D9FF", "#00000014", "#0000001E", "#0000000C", "#52C41AFF", "#FAAD14FF", "#00000073", "#0000000F", "#001529FF", "#002140FF", "#FFFFFF33", "#722ED1FF", "#13C2C2FF", "#EB2F96FF", "#F5222DFF", "#FA8C16FF", "#FADB14FF", "#FA541CFF", "#2F54EBFF", "#A0D911FF", "#000000D9", "#ADBBE0FF", "#5A71C7FF", "#FFF2F0FF", "#FFFFFFA6", "#FFFFFF00", "#FFFFFF40", "#FF7875FF", "#000C17FF", "#0543C014", "#0000000A", "#FFA39EFF", "#FF26050F", "#FFD666FF", "#FFD70519", "#D9363EFF", "#00000026", "#DDE2EDFF", "#F5F5F5FF", "#F0F0F0FF", "#D9D9D9FF", "#000FFFFF", "#000000A6", "#EBF0FAFF", "#8196D4FF", "#F6FFEDFF", "#D9F7BEFF", "#B7EB8FFF", "#95DE64FF", "#389E0DFF", "#73D13DFF", "#FFF1F0FF", "#FFCCC7FF", "#FFFBE6FF", "#FFF1B8FF", "#FFE58FFF", "#D48806FF", "#FFC53DFF", "#E6F4FFFF", "#BAE0FFFF", "#91CAFFFF", "#4096FFFF", "#FAFAFAFF", "#EDEDEDFF", "#E0E0E0FF", "#D4D4D4FF", "#C7C7C7FF", "#A1A1A1FF", "#545454FF", "#2E2E2EFF" ] let html = '<ul>' colorList.forEach((item) => { const data = determineTextColor(item) html += `<li style="background: ${item}; color: ${data}; border: 1px solid ${data};">${item}</li>` }) html += '</ul>' document.body.innerHTML = html
图片展示