【问题标题】:Create unique colors using javascript使用 javascript 创建独特的颜色
【发布时间】:2011-10-12 23:46:06
【问题描述】:

为条形图/直方图选择随机颜色的最佳方法是什么,以使每种颜色彼此不同......并且可能形成对比

最受关注的方式是

'#'+(Math.random()*0xFFFFFF<<0).toString(16);

但这会产生相似的颜色..有时区分它们可能是一个问题.. 例子

【问题讨论】:

  • 任何选择随机颜色的方法有时都会产生相似的颜色。如果您不希望它们相似,只需准备一份合适的颜色列表并从中挑选(如果您愿意,可以随机选择)。
  • 您不想使用建议的方法的最大原因是人们视觉上感知为色谱的内容与十六进制色谱不是线性成比例的。这就是为什么"web safe colors" 看起来不像彩虹。

标签: javascript histogram


【解决方案1】:

我会使用HSV(色调、饱和度、值)而不是RGB 来生成颜色。在 HSV 中,颜色由色调定义,范围为 0-360。因此,如果你想要例如6不同的颜色,你可以简单地将360除以5(因为我们要包括0)得到72,所以每种颜色都应该以72递增。使用 this one 之类的函数将生成的 HSV 颜色转换为 RGB。

以下函数以 RGB 格式返回一个由total 不同颜色组成的数组。请注意,此示例中的颜色不会是“随机”的,因为它们的范围总是从红色到粉红色。

function randomColors(total)
{
    var i = 360 / (total - 1); // distribute the colors evenly on the hue range
    var r = []; // hold the generated colors
    for (var x=0; x<total; x++)
    {
        r.push(hsvToRgb(i * x, 100, 100)); // you can also alternate the saturation and value for even more contrast between the colors
    }
    return r;
}

【讨论】:

【解决方案2】:

最好的方法是从HSV values 转换。您可以将“色调”的最大值除以您需要的颜色数量,然后按此结果递增。

为了提高对比度,您还可以在亮度的高值和低值之间交替。

【讨论】:

  • 然而,正如@Reesis 所说,均匀划分色调与挑选视觉上不同的颜色不同——与我们对​​红色的敏感性相比,我们对绿色变化的敏感性要低得多,并且(对较小的程度)蓝色。区分草和叶不如看到火重要。
  • 好点,这种方法只在需要少量不同颜色时才有效。
【解决方案3】:

提到颜色的色调、饱和度、价值表示的现有答案非常优雅,更接近人类感知颜色的方式,最好听从他们的建议。此外,创建一个预先计算的长颜色列表并根据需要选择它们的子集,既快速又可靠。

但是,这里有一些代码可以直接回答您的问题:它将在 RGB 中生成完全不同的随机颜色。我可以看到这种技术有两个缺点。首先,这些颜色真的是随机的,可能看起来有点恶心,其次,代码可能需要一段时间才能偶然发现有效的颜色,具体取决于您要求颜色“相距多远”。

function hex2rgb(h) {
    return [(h & (255 << 16)) >> 16, (h & (255 << 8)) >> 8, h & 255];
}
function distance(a, b) {
    var d = [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
    return Math.sqrt((d[0]*d[0]) + (d[1]*d[1]) + (d[2]*d[2]));
}
function freshColor(sofar, d) {
    var n, ok;
    while(true) {
        ok = true;
        n = Math.random()*0xFFFFFF<<0;
        for(var c in sofar) {
            if(distance(hex2rgb(sofar[c]), hex2rgb(n)) < d) {
                ok = false;
                break;
            }
        }
        if(ok) { return n; }
    }
}
function getColors(n, d) {
    var a = [];
    for(; n > 0; n--) {
        a.push(freshColor(a, d));
    }
    return a;
}

颜色之间的距离是由 R、G 和 B 分量测量的Euclidean distance。因此,两种颜色(黑色和白色)的最远距离约为 441.67。

要使用此代码,请调用getColors,其中第一个参数是颜色数,第二个参数是任意两个颜色之间的最小距离。它将返回一个数字 RGB 值数组。

【讨论】:

    【解决方案4】:

    我喜欢以这种方式使用 hsl 值来指定颜色。

    所以

    "color: hsl(" + getRandomArbitary(0, 360) + ", 50%, 50%)";
    

    会给你随机的结果,但这不会给你明显的分离。所以我将它基于循环的 i 值。类似的,

    for (var i = 0; i < whateverYourValue; i += 1) {
        color = "color: hsl(" + i * 10 + ", 50%, 50%)";
    
        // set your colour on whatever
    }
    

    显然以上是指示性的,本身不是有效的代码。

    想了解更多关于 hsl 的信息吗?检查http://mothereffinghsl.com/,因为,你知道,这很有趣。

    【讨论】:

      【解决方案5】:
      '#'+(Math.random()*0xFFFFFF<<0).toString(16);
      

      不是最好的使用方法,因为它可以生成像 #4567 这样缺少两位数字而不是生成 #004567 的值

      最好单独选择每个字符,例如:

      '#'+Math.floor(Math.random()*16).toString(16)+
          Math.floor(Math.random()*16).toString(16)+
          Math.floor(Math.random()*16).toString(16)+
          Math.floor(Math.random()*16).toString(16)+
          Math.floor(Math.random()*16).toString(16)+
          Math.floor(Math.random()*16).toString(16);
      

      但这可以很容易地简化为选择三个数字,因为可以缩短十六进制颜色。 IE。 #457 == #445577

      然后,如果您想减少可能性的数量并扩大它们之间的差距,您可以使用:

      '#'+(5*Math.floor(Math.random()*4)).toString(16)+
          (5*Math.floor(Math.random()*4)).toString(16)+
          (5*Math.floor(Math.random()*4)).toString(16);
      

      将每种颜色的选择数除以 5,然后平均分配。

      【讨论】:

      • 查看我对该问题的评论以获得更长的解释,但这很糟糕,因为web safe colors(颜色均匀分布在 RGB 值中)很难看。
      【解决方案6】:

      我赞同 kbok 和 Harpyon 关于在 HSV 颜色空间中工作的看法,this little library 让在 RGB 和 HSV 以及其他颜色空间之间切换变得超级容易。

      【讨论】:

        猜你喜欢
        • 2012-01-13
        • 2010-10-20
        • 1970-01-01
        • 2013-08-05
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 2010-11-13
        • 2011-03-09
        相关资源
        最近更新 更多