如何生成 RGB 的随机阴影?
Posted
技术标签:
【中文标题】如何生成 RGB 的随机阴影?【英文标题】:How can I generate random shades of an RGB? 【发布时间】:2022-01-08 11:01:51 【问题描述】:我正在尝试找到一种方法来生成 RGB 颜色的随机阴影。
正如您在 sn-p 中看到的,大多数色调都还可以,但有些颜色在视觉上完全不相关。有办法改善吗?
let resultsContainer = document.getElementById('results')
let original = r: 244, g: 102, b: 255 // generate random shades of this color
let max = 100
let min = 100
let results = []
document.getElementById('original').style.background = `rgb($original.r, $original.g, $original.b)`
function randomBetween(min, max)
min = min < 0 ? 0 : min
max = max > 255 ? 255 : max
return min + Math.floor(Math.random() * (max - min + 1))
while (results.length < 10)
results.push(
r: randomBetween(original.r-min, original.r+max),
g: randomBetween(original.g-min, original.g+max),
b: randomBetween(original.b-min, original.b+max),
)
results.forEach(( r, g, b ) =>
let result = document.createElement('div')
result.className = 'result'
result.style.background = `rgb($r, $g, $b)`
resultsContainer.appendChild(result)
)
.result
float:left;
width: 50px;
height: 50px;
<div id="original" class="result"></div>
<br>
<br>
<br>
<br>
<div id="results"></div>
我的 randomBetween() 方法的灵感来自 https://***.com/a/23095771/2272048
【问题讨论】:
最好有大量预先批准的颜色,然后从中随机提取以避免出现多个灰色。 无关紧要是什么意思? @ggorlen 在视觉上无关 毫不奇怪,每个色调,乍一看只有 5-6 个可区分的亮度级别。并且仅对于最上面的一个,您有 3 个可区分的饱和度级别,而较低的亮度值则按比例减少。因此,只有 12 种可感知的颜色才会有单一的色调可供选择。所有这些你都可以在 HSV 颜色空间中系统地构建。 抱歉,我仍然不确定“视觉相关性”对您意味着什么。灰太多了?重叠/相似的颜色太多? 【参考方案1】:最好使用 HSL(Hue ,Saturation ,Lightness) 而不是 RGB ,并且只随机化 Saturation 和 Lightness 以获得不同的色调。
更新:根据 OP 建议更新代码,HSLRGB 转换器采用here
function hslToRgb(h, s, l)
h /= 360.0, s /= 100.0, l /= 100.0;
var r, g, b;
if(s == 0)
r = g = b = l; // achromatic
else
var hue2rgb = function hue2rgb(p, q, t)
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1 / 6) return p + (q - p) * 6 * t;
if(t < 1 / 2) return q;
if(t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
return [Math.round(r * 255), Math.round(g * 255), Math.round(b *
255)];
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 * 360, s * 100, l * 100]
function randomBetween(min, max)
min = min < 10 ? 10 : min // under 10 it becomes too dark
max = max > 90 ? 90 : max // over 90 it becomes too light
return min + Math.floor(Math.random() * (max - min + 1))
let resultsContainer = document.getElementById('results')
let originalAsRGB = [244, 102, 255]
let originalAsHSL = rgbToHsl(
originalAsRGB[0],
originalAsRGB[1],
originalAsRGB[2]
)
let max = 40
let min = 40
let results = []
document.getElementById('original-as-rgb')
.style.background =
`rgb($originalAsRGB[0], $originalAsRGB[1],
$originalAsRGB[2])`
document.getElementById('original-as-hsl')
.style.background =
`hsl($originalAsHSL[0]deg, $originalAsHSL[1]%,
$originalAsHSL[2]%)`
while(results.length < 10)
results.push(
h: originalAsHSL[0],
s: randomBetween(originalAsHSL[1] - min, originalAsHSL[1] +
max),
l: randomBetween(originalAsHSL[2] - min, originalAsHSL[2] +
max)
)
results.forEach((h,s,l) =>
let result = document.createElement('div')
result.className = 'result'
let [r, g, b] = hslToRgb(h, s, l)
result.style.background = `rgb($r, $g, $b)`
resultsContainer.appendChild(result)
)
.result
float:left;
width: 50px;
height: 50px;
<strong>original RGB:</strong>
<br>
<div id="original-as-rgb" class="result"></div>
<br>
<br>
<br>
<br>
<strong>original RGB converted to HSL:</strong>
<br>
<div id="original-as-hsl" class="result"></div>
<br>
<br>
<br>
<br>
<strong>random shades of the above HSL:</strong>
<br>
<div id="results"></div>
【讨论】:
我现在的问题是我需要将 RGB 转换为 HSL。我找不到这样做的方法。 @SproutCoder 有一个很好的解决方案here,但是你可能需要做一些转换 @SproutCoder 抱歉回复迟了,在 jsfiddle 中,第 44 行必须是:return [h*360, s*100, l*100];
@SproutCoder 哈哈,我们在不同的时区,答案更新了,唯一的变化是在hslToRgb
的开头添加以下内容=> h /= 360.0, s /= 100.0, l /= 100.0;
感谢您花时间更新
【参考方案2】:
要对 RGB 进行着色,请将每个 r、g、b 乘以一个百分比。 要着色,对于每个 r、g、b,使用:color + value% * (255 - color)。 轻松愉快。
【讨论】:
以上是关于如何生成 RGB 的随机阴影?的主要内容,如果未能解决你的问题,请参考以下文章