如何 "sort" 特定色调的颜色

How to "sort" colors of a particular hue

因此,如果我使用 randomColor 来生成 "green" 的相当随机的变化,我会得到以下示例:

这对我来说有点混乱,我想得到一个绿色列表,这些颜色具有某种 ordersorting 给他们。看起来它们相互流入。更像是这样的:

问题是使用什么原则以这种方式对颜色进行排序。我想知道如何构建一个颜色网格,它看起来比特定色调的随机颜色组合更令人愉悦。

我使用的代码很简单:

var randomColor = require('randomcolor')

var input = process.argv[2]
var colors = randomColor({
  count: 20,
  hue: input
})

如果它有所不同,我希望能够指定行数和列数来划分颜色。任何语言或伪代码都可以很好地解决这个问题,但在 JavaScript 中看到它,特别是如果它涉及位操作(如位移),将会有所帮助,但不是必需的。

This 似乎不太符合我的要求。

(不打算将此作为包含完整代码的答案)

你在第二张图片中的绿色,在顶部 运行 从蓝绿色到黄绿色。实际上,这意味着左上角的绿色是“0 红色,可能是 255 绿色和 200 蓝色”。在另一边,在右上角,它可能是“200 red, 255 green, 0 blue”。 (我本来可以通过使用颜色检测器使这些更准确,但我在 phone)

通过降低 r g b 值,它们会沿着行向下下降到黑色,因此对于中间行,它们可能会从 rgb 0,127,100 变为 rgb 100,127,0

从算法上讲,尽管使用 hsv 颜色而不是 rgb 颜色可能更容易做到这一点,因为横跨的列从一些较高的色调变为较低的色调,并且向下的行趋向于从高值变为低值。这可能比做 rgb 数学更容易实现,因为你只需要接受一个可能从 h+40 到 h-40(从一个完整的 360 轮)和一个矩阵(你可能需要要求行和列不只是 20,否则你怎么知道输出 5x4 或 4x5)

图像上的绿色 运行 随着您向下移动,它们会随着各种色调的变化而降低(黑色变少)。

你漂亮的颜色生成器 randomColor 是基于一个奇怪的理论,即在颜色 space 内通过黄金比例移动的颜色会更漂亮,基本上它只是确保你倾向于获得线性步骤。但是,该代码是 CC0 许可的,并且包含许多对您有用的东西。首先,他们定义了什么是绿色。他们定义了如何从 RGB 转换为 HSL。我只是更改该代码以通过正确的色调进行线性步进,然后在行方向上逐步增加值。

但是,这将每次都创建相同的颜色,因此您可以只定义您喜欢的绿色列表。

如果你真的想对这些颜色进行排序,你可以按照字面上的排序来对它们进行排序。在代码 randomColor 中使用 HexToHSB(),然后根据生成的色调值对值进行排序。这通常会有越来越亮的颜色,但您可以清楚地看到整个图案不那么混乱。

所有颜色 space 往往是 3 个值,因此将它们放在 2d 中往往有点笨拙,因此您不妨选择一两个指标并使用它们。

  function HexToHSB(hex) {
    hex = hex.replace(/^#/, '');
    hex = hex.length === 3 ? hex.replace(/(.)/g, '') : hex;

    var red = parseInt(hex.substr(0, 2), 16) / 255,
      green = parseInt(hex.substr(2, 2), 16) / 255,
      blue = parseInt(hex.substr(4, 2), 16) / 255;

    var cMax = Math.max(red, green, blue),
      cMin = Math.min(red, green, blue),
      delta = cMax - cMin,
      saturation = cMax ? (delta / cMax) : 0;

    switch (cMax) {
      case 0:
        return [0, 0, 0];
      case cMin:
        return [0, 0, cMax];
      case red:
        return [60 * (((green - blue) / delta) % 6) || 0, saturation, cMax];
      case green:
        return [60 * (((blue - red) / delta) + 2) || 0, saturation, cMax];
      case blue:
        return [60 * (((red - green) / delta) + 4) || 0, saturation, cMax];
    }
  }

  var input = 'green'
  var colors = randomColor({
    count: 200,
    hue: input
  })
  colors = colors.sort(function(a, b) {
    var hsva = HexToHSB(a);
    var hsvb = HexToHSB(b);
    return hsva[0] - hsvb[0];
  });
  div = document.createElement("div");
  document.body.appendChild(div);
  colors.forEach(function(element) {
    var d = document.createElement("button");
    d.style.cssText = 'padding:5px; font-size:22px; width:50px; height:50px; background-color:' + element;
    div.appendChild(d);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.5.4/randomColor.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>