如何生成 RGB 的随机阴影?

How can I generate random shades of an RGB?

我正在尝试找到一种生成 RGB 颜色随机阴影的方法。

正如您在代码片段中看到的那样,大多数色调都还不错,但有些色调在视觉上完全不相关。有没有办法改善这个?

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>

而不是 RGB ,最好使用 HSL(色调,饱和度,亮度),并且只随机化饱和度和亮度以获得不同的阴影。

更新: 根据 OP 建议更新代码,HSL<->RGB 转换器采用 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 进行着色,请将每个 r、g、b 乘以一个百分比。 要为每个 r、g、b 着色,请使用:color + value% * (255 - color)。 简单易行。