I’m trying to find a way to generate random shades of an RGB color.
As you can see in the snippet, most shades are pretty ok but there are some that are completely irrelevant visually. Is there a way of improving this ?
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>
- My randomBetween() method is inspired by https://stackoverflow.com/a/23095771/2272048
>Solution :
instead of RGB , it’s better to use HSL( Hue ,Saturation ,Lightness) , and only randomize Saturation and Lightness to get different shades.
let resultsContainer = document.getElementById('results')
let original = { h: 296, s: 100, l: 70 } // generate random shades of this color
let max = 40
let min = 40
let results = []
document.getElementById('original').style.background = `hsl(${original.h}deg, ${original.s}%, ${original.l}%)`
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))
}
while (results.length < 10) {
results.push({
h: original.h,
s: randomBetween(original.s-min, original.s+max),
l: randomBetween(original.l-min, original.l+max),
})
}
results.forEach(({ h, s, l }) => {
let result = document.createElement('div')
result.className = 'result'
result.style.background = `hsl(${h}deg, ${s}%, ${l}%)`
resultsContainer.appendChild(result)
})
.result {
float:left;
width: 50px;
height: 50px;
}
<div id="original" class="result"></div>
<br>
<br>
<br>
<br>
<div id="results"></div>