javascript/jquery を使用して、rgba 値の配列を可視スペクトルの色に並べ替えたいと考えています。こうすることで、似たような色合いがまとまるはずです。これを行うためのプラグインはありますか、それともどうすればよいですか?
スペクトル画像: http://www.gamonline.com/catalog/colortheory/images/spectrum.gif
javascript/jquery を使用して、rgba 値の配列を可視スペクトルの色に並べ替えたいと考えています。こうすることで、似たような色合いがまとまるはずです。これを行うためのプラグインはありますか、それともどうすればよいですか?
スペクトル画像: http://www.gamonline.com/catalog/colortheory/images/spectrum.gif
開示:私は、以下で推奨されるライブラリの作成者です。
ライブラリの使用を気にしない場合は、Oriol の詳細な応答のより簡潔なバージョンを次に示します。sc-color ライブラリを使用します。
var sorted = colorArray.sort(function(colorA, colorB) {
return sc_color(colorA).hue() - sc_color(colorB).hue();
});
色の配列が次のような場合:
var rgbArr = [c1, c2, c3, ...]
ここで、各色ci
は 0 から 255 までの 3 つの数値の配列です
ci = [red, green, blue]
次に、この関数を使用して色を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);
}
色相で並べ替えます
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];
});
これは実行可能な例です ( 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);
#before > div,
#after > div {
width: 1%;
height: 20px;
display: inline-block;
}
Random colors: <div id="before"></div>
Same colors, sorted by hue: <div id="after"></div>
sortedRgbArr
rgbArr
多かれ少なかれ可視スペクトルの色のようにソートされたRGBカラーが含まれます。
問題は、HSL スペクトルが次のようになることです。
ピンクなどのすべての色が含まれているわけではないため、スペクトルは奇妙です。
ピンクは自然界に存在せず、光のスペクトルの両極端の色の組み合わせだからだと思います。しかし、私たちはRGBでそれを持っているので、あなたはそれをどこに置くかを決める必要があります.
さらに、あなたのスペクトルは、周波数ではなく、より低い波長からより高い波長に向かっているようです. しかし、あなたのスペクトルは HSL のスペクトルの逆です。
あなたのスペクトルのようにしたい場合は、に置き換えc1.color[0] - c2.color[0]
てください。c2.color[0] - c1.color[0]