如何生成指定RGB颜色的随机深浅色并优化视觉不符的异常结果
问题原因
原实现直接对R、G、B三个通道单独做随机增减,会破坏三个通道的原始比例,导致颜色色相发生偏移,因此会出现生成的色值和原颜色视觉无关的问题。
优化方案
要保证生成的深浅色都属于原色系,核心是保留原颜色的色相不变,仅调整明度、可小范围调整饱和度。我们可以先将RGB颜色转换为HSV(色相/饱和度/明度)色彩空间,在HSV空间做随机调整后再转回RGB即可规避色相偏移问题。
优化后完整代码
JS代码
let resultsContainer = document.getElementById('results') let original = { r: 244, g: 102, b: 255 } // 可调整参数:控制深浅波动范围、饱和度波动范围 const lightnessRange = 30 // 明度波动幅度,数值越大深浅差异越大 const saturationRange = 10 // 饱和度波动幅度,数值越大色彩鲜艳度差异越大 let results = [] document.getElementById('original').style.background = `rgb(${original.r}, ${original.g}, ${original.b})` // RGB转HSV工具函数 function rgbToHsv(r, g, b) { r /= 255, g /= 255, b /= 255 let max = Math.max(r, g, b), min = Math.min(r, g, b) let h, s, v = max let d = max - min s = max == 0 ? 0 : d / max if (max == min) { h = 0 } else { 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, v } } // HSV转RGB工具函数 function hsvToRgb(h, s, v) { let r, g, b let i = Math.floor(h * 6) let f = h * 6 - i let p = v * (1 - s) let q = v * (1 - f * s) let t = v * (1 - (1 - f) * s) switch (i % 6) { case 0: r = v, g = t, b = p; break case 1: r = q, g = v, b = p; break case 2: r = p, g = v, b = t; break case 3: r = p, g = q, b = v; break case 4: r = t, g = p, b = v; break case 5: r = v, g = p, b = q; break } return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) } } function randomBetween(min, max) { return min + Math.floor(Math.random() * (max - min + 1)) } const originalHsv = rgbToHsv(original.r, original.g, original.b) while (results.length < 10) { // 仅调整明度和饱和度,色相保持不变 const newV = Math.max(0, Math.min(1, originalHsv.v + randomBetween(-lightnessRange, lightnessRange)/100)) const newS = Math.max(0, Math.min(1, originalHsv.s + randomBetween(-saturationRange, saturationRange)/100)) const newRgb = hsvToRgb(originalHsv.h, newS, newV) results.push(newRgb) } results.forEach(({ r, g, b }) => { let result = document.createElement('div') result.className = 'result' result.style.background = `rgb(${r}, ${g}, ${b})` resultsContainer.appendChild(result) })
CSS代码
.result { float:left; width: 50px; height: 50px; }
HTML代码
<div id="original" class="result"></div> <br> <br> <br> <br> <div id="results"></div>
参数调整说明
- 增大
lightnessRange数值可以让生成的颜色深浅差异更大,减小则更接近原色彩的明暗 - 增大
saturationRange数值可以让生成的颜色鲜艳度差异更大,如果不需要调整饱和度直接设置为0即可
内容的提问来源于stack exchange,提问作者user2272048
相关产品推荐
相关产品推荐

