【问题标题】:How can I generate colors (not by chance) and so that they have a different color, not a shade?我怎样才能生成颜色(不是偶然),使它们具有不同的颜色,而不是阴影?
【发布时间】:2020-05-27 09:53:14
【问题描述】:

是否有可能“添加”另一种颜色,并基本上让它从中断的地方重新开始?例如,假设您从 30 个项目开始着色,但用户添加了第 31 个项目。有没有办法让它继续其当前生成的集合并简单地生成符合先前色调和步骤的第 31 种颜色? 找到了一个例子,但是不明白怎么用

function rainbow(numOfSteps, step) {
    // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
    // Adam Cole, 2011-Sept-14
    // HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
    var r, g, b;
    var h = step / numOfSteps;
    var i = ~~(h * 6);
    var f = h * 6 - i;
    var q = 1 - f;
    switch(i % 6){
        case 0: r = 1; g = f; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = f; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = f; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
    }
    var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
    return (c);
}

【问题讨论】:

    标签: javascript rgb


    【解决方案1】:

    拥有 32 种实际上看起来独一无二的颜色并不容易。特别是如果您只想改变色调,您可以在这里看到 32 种颜色,只改变色调

    const hsl = (h, s, l) => `hsl(${h * 360 | 0},${s * 100}%,${l * 100}%)`;
    for (let i = 0; i < 32; ++i) {
      const div = document.createElement('div');
      div.style.background = hsl(i / 32, 1, 0.5);
      div.className = 'b';
      document.body.appendChild(div);
    }
    .b {
     width: 32px;
     height: 32px;
     display: inline-block;
    }

    您可以尝试使用不同的颜色空间,例如 HCL,但这同样存在问题

    for (let i = 0; i < 32; ++i) {
      const div = document.createElement('div');
      div.style.background  = chroma.hcl(i / 32 * 360, 80, 70).css();
      div.className = 'b';
      document.body.appendChild(div);
    }
    .b {
     width: 32px;
     height: 32px;
     display: inline-block;
    }
    &lt;script src="https://cdn.jsdelivr.net/npm/chroma-js@2.1.0/chroma.min.js"&gt;&lt;/script&gt;

    我建议您也考虑更改亮度。例如 16 种浅色和 16 种深色

    但我更建议您考虑添加模式。例如平面 vs 格子 vs 垂直条纹 vs 水平条纹 vs 斜条纹 vs 菱形等等...

    或符号♠️ ♦️ ♣️ ♥ ◾️ ● ▲ 等。

    至于选择距离最远的颜色,您可以反转 int 的位,但您需要预先选择范围。例如,如果我们选择 0 到 255(8 位)的范围,那么通过反转位,前 2 个项目将是最大距离。 (0 和 128)。接下来的 2 将是这 2 个(64 和 192)之间的最大距离。接下来的 4 个将是每个(32、96、160、224)等之间的最大值......

    this

    【讨论】:

      【解决方案2】:

      如果要保持色相,先从 HSV/HSL 开始,再转为 RGB 会更容易:

          function generateHslaColors (saturation, lightness, alpha, amount) {
            let colors = []
            let huedelta = Math.trunc(360 / amount)
      
            for (let i = 0; i < amount; i++) {
              let hue = i * huedelta
              colors.push(`hsla(${hue},${saturation}%,${lightness}%,${alpha})`)
            }
      
            return colors
          }
      
          /**
           * Converts an HSL color value to RGB. Conversion formula
           * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
           * Assumes h, s, and l are contained in the set [0, 1] and
           * returns r, g, and b in the set [0, 255].
           *
           * @param   {number}  h       The hue
           * @param   {number}  s       The saturation
           * @param   {number}  l       The lightness
           * @return  {Array}           The RGB representation
           */
          function hslToRgb(h, s, l){
              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)];
          }
      

      【讨论】:

      • 请避免发帖link only answers。这应该是评论,或者您需要在问题本身中包含这些链接的基本部分
      【解决方案3】:

      我找到了一个例子,但我不明白它是如何使用的

      您需要决定要将渐变分割成多少个不同的段。然后循环该total 并生成渐变的每个段,如下所示:

      function rainbow(numOfSteps, step) {
          // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
          // Adam Cole, 2011-Sept-14
          // HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
          var r, g, b;
          var h = step / numOfSteps;
          var i = ~~(h * 6);
          var f = h * 6 - i;
          var q = 1 - f;
          switch(i % 6){
              case 0: r = 1; g = f; b = 0; break;
              case 1: r = q; g = 1; b = 0; break;
              case 2: r = 0; g = 1; b = f; break;
              case 3: r = 0; g = q; b = 1; break;
              case 4: r = f; g = 0; b = 1; break;
              case 5: r = 1; g = 0; b = q; break;
          }
          var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
          return (c);
      }
      
      const total = 100;
      for (let i = 0; i < total; i++) {
        const $div = document.createElement('div');
        $div.className = 'box';
        $div.style.background = rainbow(total, i);
        document.body.appendChild($div);
      }
      .box {
        position: relative;
        width: 100%;
        height: 10px;
      }

      【讨论】:

      • 不过,绿色阴影无法区分。
      • @D.Pardal OP 询问他应该如何使用他找到的代码。我没有写算法。如果 OP:s 的问题在于算法的结果,那么应该在问题中表达出来。
      • Olian04 谢谢)我如何在java中实现这个? ~~ 我在 Math.floor 上改变了这个,但它对我不起作用(
      猜你喜欢
      • 2017-03-29
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2014-05-14
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多