二维排序颜色

时间:2019-01-24 21:28:08

标签: javascript algorithm sorting colors

对于Web项目的需求,我想从定义的颜色列表中生成颜色选择器。这是我所做的:

unsorted color picker

如您所见,颜色没有排序。我发现了很多算法可以对颜色进行排序,但不是二维算法。我想要的结果是这样的:

sorted color picker

您对我能做什么有任何想法吗?谢谢。

如果您想知道,我已经看过this post了,但问题并不相同:我还不知道50%颜色的最终位置。

这里尝试在x轴上按红色排序,在y轴上按绿色排序:

red green sorted color picker

3 个答案:

答案 0 :(得分:2)

第二张图像不仅仅是具有某种颜色排序的矩阵。从某个角度看,它实际上是3-D颜色模型的一部分。颜色模型是一种可视化视图,可显示多维光谱。诸如GIMP之类的工具向您展示了此类频谱的一部分。

例如,考虑一个具有原始顶点(0,0,0)的立方体。对于RGB,每个轴都不过是一个介于0到255之间的颜色值范围。沿着X轴,我们的R值是0到255,沿着Y轴我们的G值是0到255,沿着z轴我们B值从0到255。在原点(0,0,0),我们有黑色。在另一端,我们有一个白色的顶点(255,255,255)。您可以通过沿轴更改值来获得任何颜色值。

有关更多详细信息,您可能需要阅读:https://programmingdesignsystems.com/color/color-models-and-color-spaces/index.html

答案 1 :(得分:1)

您可以将颜色从RGB转换为HSL,然后在“色相”和“饱和度”(例如x / y)上进行排序。

要像在第二张图像中那样订购颜色,您可以想到色相位于色轮上并转换为适合正方形或矩形的x / y位置。

或者,您也可以按照评论中已经提到的方式对红色/绿色(x / y)进行排序(显示的额外图像不会按红色/绿色进行排序)。

答案 2 :(得分:0)

感谢您的帮助Danny_dsHarsh Gupta。 我试图制作一个在X和Y轴上都“发臭”的拾色器。我尝试了十二种不同的算法,但看起来并不好。所以现在,我只在一个轴上排序,然后对每条线进行排序。结果看起来非常好:

sorted color picker

以下是来源:

 if (settings != null && settings.checkSubscriptionForVip === true) {
            return this.user.hasVipAccess().then(function(hasVipAccess) {

              hasVipAccess ? deferred.resolve() : deferred.reject("NO_VIP");
              return;
            });
          } else {
            deferred.resolve();
            return;
          }
'use strict';

let colors = [{
		"name": "Black",
		"hexa": "000000"
	},
	{
		"name": "Sable",
		"hexa": "202020"
	},
	{
		"name": "Grey/Gray",
		"hexa": "808080"
	},
	{
		"name": "Argent",
		"hexa": "E5E5E5"
	},
	{
		"name": "Silver",
		"hexa": "C0C0C0"
	},
	{
		"name": "White",
		"hexa": "FFFFFF"
	},
	{
		"name": "Snow",
		"hexa": "FFFAFA"
	},
	{
		"name": "Gainsboro",
		"hexa": "DCDCDC"
	},
	{
		"name": "Linen",
		"hexa": "FAF0E6"
	},
	{
		"name": "Wheat",
		"hexa": "F5DEB3"
	},
	{
		"name": "Antiquewhite",
		"hexa": "FAEBD7"
	},
	{
		"name": "Darkgray",
		"hexa": "A9A9A9"
	},
	{
		"name": "Dimgray",
		"hexa": "696969"
	},
	{
		"name": "Floralwhite",
		"hexa": "FFFAF0"
	},
	{
		"name": "Ghostwhite",
		"hexa": "F8F8FF"
	},
	{
		"name": "Lightgray",
		"hexa": "D3D3D3"
	},
	{
		"name": "Lightslategray",
		"hexa": "778899"
	},
	{
		"name": "Red",
		"hexa": "FF0100"
	},
	{
		"name": "Brown",
		"hexa": "A52A2A"
	},
	{
		"name": "Maroon",
		"hexa": "800000"
	},
	{
		"name": "Gules",
		"hexa": "DD0100"
	},
	{
		"name": "Crimson",
		"hexa": "DC143C"
	},
	{
		"name": "Indianred",
		"hexa": "CD5C5C"
	},
	{
		"name": "Orangered",
		"hexa": "FF4501"
	},
	{
		"name": "Mistyrose",
		"hexa": "FFE4E1"
	},
	{
		"name": "Darkred",
		"hexa": "8B0000"
	},
	{
		"name": "Firebrick",
		"hexa": "B22222"
	},
	{
		"name": "Lightsalmon",
		"hexa": "FFA07A"
	},
	{
		"name": "Orange",
		"hexa": "FFA502"
	},
	{
		"name": "Gold",
		"hexa": "FFD702"
	},
	{
		"name": "Or",
		"hexa": "FFE403"
	},
	{
		"name": "Chocolate",
		"hexa": "D2691E"
	},
	{
		"name": "Coral",
		"hexa": "FF7F50"
	},
	{
		"name": "Lightcoral",
		"hexa": "F08080"
	},
	{
		"name": "Moccasin",
		"hexa": "FFE4B5"
	},
	{
		"name": "Navajowhite",
		"hexa": "FFDEAD"
	},
	{
		"name": "Darkorange",
		"hexa": "FF8C01"
	},
	{
		"name": "Yellow",
		"hexa": "FFFF03"
	},
	{
		"name": "Tan",
		"hexa": "D2B48C"
	},
	{
		"name": "Bisque",
		"hexa": "FFE4C4"
	},
	{
		"name": "Ivory",
		"hexa": "FFFFF0"
	},
	{
		"name": "Beige",
		"hexa": "F5F5DC"
	},
	{
		"name": "Cornsilk",
		"hexa": "FFF8DC"
	},
	{
		"name": "Goldenrod",
		"hexa": "DAA520"
	},
	{
		"name": "Khaki",
		"hexa": "F0E68C"
	},
	{
		"name": "Lemonchiffon",
		"hexa": "FFFACD"
	},
	{
		"name": "Blanchedalmond",
		"hexa": "FFEBCD"
	},
	{
		"name": "Burlywood",
		"hexa": "DEB887"
	},
	{
		"name": "Darkgoldenrod",
		"hexa": "B8860B"
	},
	{
		"name": "Darkkhaki",
		"hexa": "BDB76B"
	},
	{
		"name": "Yellowgreen",
		"hexa": "9ACD32"
	},
	{
		"name": "Lightgoldenrodyellow",
		"hexa": "FAFAD2"
	},
	{
		"name": "Lightyellow",
		"hexa": "FFFFE0"
	},
	{
		"name": "Oldlace",
		"hexa": "FDF5E6"
	},
	{
		"name": "Palegoldenrod",
		"hexa": "EEE8AA"
	},
	{
		"name": "Papayawhip",
		"hexa": "FFEFD5"
	},
	{
		"name": "Green",
		"hexa": "018001"
	},
	{
		"name": "Vert",
		"hexa": "019301"
	},
	{
		"name": "Lime",
		"hexa": "04FF03"
	},
	{
		"name": "LightGreen",
		"hexa": "90EE90"
	},
	{
		"name": "Olive",
		"hexa": "808001"
	},
	{
		"name": "Chartreuse",
		"hexa": "7FFF03"
	},
	{
		"name": "Honeydew",
		"hexa": "F0FFF0"
	},
	{
		"name": "Springgreen",
		"hexa": "06FF7F"
	},
	{
		"name": "Mediumseagreen",
		"hexa": "3CB371"
	},
	{
		"name": "Lawngreen",
		"hexa": "7CFC03"
	},
	{
		"name": "Darkgreen",
		"hexa": "016400"
	},
	{
		"name": "Darkolivegreen",
		"hexa": "556B2F"
	},
	{
		"name": "Seagreen",
		"hexa": "2E8B57"
	},
	{
		"name": "Darkseagreen",
		"hexa": "8FBC8F"
	},
	{
		"name": "Darkslategray",
		"hexa": "2F4F4F"
	},
	{
		"name": "Forestgreen",
		"hexa": "228B22"
	},
	{
		"name": "Greenyellow",
		"hexa": "ADFF2F"
	},
	{
		"name": "Lightseagreen",
		"hexa": "20B2AA"
	},
	{
		"name": "Mediumaquamarine",
		"hexa": "66CDAA"
	},
	{
		"name": "Mediumspringgreen",
		"hexa": "07FA9A"
	},
	{
		"name": "Mintcream",
		"hexa": "F5FFFA"
	},
	{
		"name": "Palegreen",
		"hexa": "98FB98"
	},
	{
		"name": "Azure/Blue",
		"hexa": "0800FF"
	},
	{
		"name": "Teal",
		"hexa": "038080"
	},
	{
		"name": "Cyan/Aqua",
		"hexa": "0CFFFF"
	},
	{
		"name": "Turquoise",
		"hexa": "40E0D0"
	},
	{
		"name": "Lightblue",
		"hexa": "ADD8E6"
	},
	{
		"name": "Navy",
		"hexa": "020080"
	},
	{
		"name": "Lightcyan",
		"hexa": "E0FFFF"
	},
	{
		"name": "Midnightblue",
		"hexa": "191970"
	},
	{
		"name": "Slateblue",
		"hexa": "6A5ACD"
	},
	{
		"name": "Cadetblue",
		"hexa": "5F9EA0"
	},
	{
		"name": "Aliceblue",
		"hexa": "F0F8FF"
	},
	{
		"name": "Aquamarine",
		"hexa": "7FFFD4"
	},
	{
		"name": "Cornflowerblue",
		"hexa": "6495ED"
	},
	{
		"name": "Darkblue",
		"hexa": "02008B"
	},
	{
		"name": "Darkcyan",
		"hexa": "038B8B"
	},
	{
		"name": "Darkslateblue",
		"hexa": "483D8B"
	},
	{
		"name": "Darkturquoise",
		"hexa": "08CED1"
	},
	{
		"name": "Deepskyblue",
		"hexa": "0ABFFF"
	},
	{
		"name": "Dodgerblue",
		"hexa": "1E90FF"
	},
	{
		"name": "Lightskyblue",
		"hexa": "87CEFA"
	},
	{
		"name": "Lightsteelblue",
		"hexa": "B0C4DE"
	},
	{
		"name": "Mediumslateblue",
		"hexa": "7B68EE"
	},
	{
		"name": "Mediumturquoise",
		"hexa": "48D1CC"
	},
	{
		"name": "Paleturquoise",
		"hexa": "AFEEEE"
	},
	{
		"name": "Indigo",
		"hexa": "4B0082"
	},
	{
		"name": "Violet",
		"hexa": "EE82EE"
	},
	{
		"name": "Purple",
		"hexa": "800080"
	},
	{
		"name": "Lavender",
		"hexa": "E6E6FA"
	},
	{
		"name": "Plum",
		"hexa": "DDA0DD"
	},
	{
		"name": "Mediumpurple",
		"hexa": "9370DB"
	},
	{
		"name": "Blueviolet",
		"hexa": "8A2BE2"
	},
	{
		"name": "Darkmagenta",
		"hexa": "8B008B"
	},
	{
		"name": "Darkviolet",
		"hexa": "9400D3"
	},
	{
		"name": "Pink",
		"hexa": "FFC0CB"
	},
	{
		"name": "Fuchsia/Magenta",
		"hexa": "FF00FF"
	},
	{
		"name": "Purpure",
		"hexa": "B31F85"
	},
	{
		"name": "Orchid",
		"hexa": "DA70D6"
	},
	{
		"name": "Hotpink",
		"hexa": "FF69B4"
	},
	{
		"name": "Darkorchid",
		"hexa": "9932CC"
	},
	{
		"name": "Darksalmon",
		"hexa": "E9967A"
	},
	{
		"name": "Deeppink",
		"hexa": "FF1493"
	},
	{
		"name": "Lavenderblush",
		"hexa": "FFF0F5"
	},
	{
		"name": "Lightpink",
		"hexa": "FFB6C1"
	}
];

function hexToRgbColor(hexColor) {
	return [
		parseInt(hexColor.substr(0, 2), 16),
		parseInt(hexColor.substr(2, 2), 16),
		parseInt(hexColor.substr(4, 2), 16)
	];
}

function rgbToHsvColor(rgbColor) {

	const r = rgbColor[0];
	const g = rgbColor[1];
	const b = rgbColor[2];

	let rabs, gabs, babs, rr, gg, bb, h, s, v, diff, diffc, percentRoundFn;
	rabs = r / 255;
	gabs = g / 255;
	babs = b / 255;
	v = Math.max(rabs, gabs, babs);
	diff = v - Math.min(rabs, gabs, babs);
	diffc = c => (v - c) / 6 / diff + 1 / 2;
	percentRoundFn = num => Math.round(num * 100) / 100;
	if (diff == 0) {
		h = s = 0;
	} else {
		s = diff / v;
		rr = diffc(rabs);
		gg = diffc(gabs);
		bb = diffc(babs);

		if (rabs === v) {
			h = bb - gg;
		} else if (gabs === v) {
			h = (1 / 3) + rr - bb;
		} else if (babs === v) {
			h = (2 / 3) + gg - rr;
		}
		if (h < 0) {
			h += 1;
		} else if (h > 1) {
			h -= 1;
		}
	}
	return [
		Math.round(h * 360),
		percentRoundFn(s * 100),
		percentRoundFn(v * 100)
	];
}

function rgbToLuminance(rgbColor) {
  return Math.sqrt(.299*rgbColor[0]*rgbColor[0] + .587*rgbColor[1]*rgbColor[1] + .114*rgbColor[2]*rgbColor[2]);
}

function sortArray(array, compareValueGetter) {

	array.sort((elem1, elem2) => {
		const value1 = compareValueGetter(elem1);
		const value2 = compareValueGetter(elem2);
		return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0);
	});
}

const nbOfColumns = 11;
const palette = document.getElementById('palette');

for (const color of colors) {
	color.rgb = hexToRgbColor(color.hexa);
	color.hsv = rgbToHsvColor(color.rgb, false);
	color.luminance = rgbToLuminance(color.rgb);
}

sortArray(colors, color => color.hsv[0]);

let sortedColors = [];
let line;

while (colors.length > 0) {

	line = colors.splice(0, nbOfColumns);
	sortArray(line, color => color.luminance)
	sortedColors = sortedColors.concat(line);
}

let tile;
for (const color of sortedColors) {
	tile = document.createElement('div');
	tile.style.backgroundColor = '#'+color.hexa;
	palette.appendChild(tile);
}
#palette{
	width: 220px;
	display: flex;
	flex-wrap: wrap;
}

#palette>div{
	cursor: pointer;
	width: 20px;
	height: 20px;
}

#palette div:hover::after{
	content: "";
	display: block;
	width: 20px;
	height: 20px;
	border: 2px solid black;
	z-index: 1;
	position: relative;
	top: -2px;
	left: -2px;
}