Javascript - 排序rgb值

And*_*zyc 4 javascript arrays sorting colors

使用javascript/jquery,我想将rgba值数组排序为可见光谱的颜色.通过这样做,像阴影应该聚集在一起.是否有插件可以执行此操作或我将如何执行此操作?

频谱图片:http://www.gamonline.com/catalog/colortheory/images/spectrum.gif

Ben*_*Ben 14

披露:我是下面推荐的图书馆的作者.

如果您不介意使用库,这里是Oriol详细响应的更简洁版本.它使用sc-color库:

var sorted = colorArray.sort(function(colorA, colorB) {
    return sc_color(colorA).hue() - sc_color(colorB).hue();
});
Run Code Online (Sandbox Code Playgroud)

  • 这真的是一个很棒的图书馆,谢谢. (3认同)

Ori*_*iol 7

如果你的颜色数组是这样的:

var rgbArr = [c1, c2, c3, ...]
Run Code Online (Sandbox Code Playgroud)

其中每种颜色ci是0到255之间的三个数字的数组

ci = [red, green, blue]
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用此功能将颜色转换为HSL

function rgbToHsl(c) {
  var r = c[0]/255, g = c[1]/255, b = c[2]/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 new Array(h * 360, s * 100, l * 100);
}
Run Code Online (Sandbox Code Playgroud)

并按色调对它们进行排序

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and keep track of original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});
Run Code Online (Sandbox Code Playgroud)

这是一个可运行的例子(感谢IonicăBizău):

function display(container, arr) {
  container = document.querySelector(container);
  arr.forEach(function(c) {
    var el = document.createElement("div");
    el.style.backgroundColor = "rgb(" + c.join(", ") + ")";
    container.appendChild(el);
  })
}
function rgbToHsl(c) {
  var r = c[0] / 255,
      g = c[1] / 255,
      b = c[2] / 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 new Array(h * 360, s * 100, l * 100);
}

var rgbArr = [];
for (var i = 0; i < 100; ++i) {
  rgbArr.push([
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256)
  ]);
}
display("#before", rgbArr);

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and keep track of original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});
display("#after", sortedRgbArr);
Run Code Online (Sandbox Code Playgroud)
#before > div,
#after > div {
  width: 1%;
  height: 20px;
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
Random colors: <div id="before"></div>
Same colors, sorted by hue: <div id="after"></div>
Run Code Online (Sandbox Code Playgroud)

sortedRgbArr将包含的rgb颜色rgbArr或多或少类似于可见光谱的颜色.

问题是HSL频谱看起来像这样:

HSL谱

你的光谱很奇怪,因为它没有所有的颜色,比如粉红色.

我猜这是因为粉红色在自然界中不存在,它是光谱相反极端的颜色的组合.但我们在rgb中有它,所以你必须决定你想要它在哪里.

此外,您的频谱似乎从较低波长到较高波长,而不是频率.但是,你的频谱与HSL频谱相反.

更换c1.color[0] - c2.color[0]c2.color[0] - c1.color[0],如果你想让它像你的频谱.