javascript - 在二维中对颜色进行排序

标签 javascript algorithm sorting colors

为了网络项目的需要,我想从定义的颜色列表中生成一个颜色选择器。这是我所做的:

unsorted color picker

如您所见,颜色未排序。我发现了很多算法来对颜色进行排序,但不是在 2D 中。我想要的结果是这样的:

sorted color picker

你知道我能做什么吗?谢谢。

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

这里是一个尝试在 x 轴上按红色排序,在 y 轴上按绿色排序的示例:

red green sorted color picker

最佳答案

感谢您的帮助Danny_dsHarsh Gupta . 我试图制作一个在 X 轴和 Y 轴上都是“smouth”的颜色选择器。我已经尝试了十几种不同的算法,但它看起来并不好。所以现在,我只在一个轴上排序,然后对每一行进行排序。结果看起来非常好:

sorted color picker

这是来源:

'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;
}
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
	<div id="palette"></div>
</body>
</html>

关于javascript - 在二维中对颜色进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54355556/

相关文章:

c++ - STL 排序是使用交换还是二进制复制?

javascript - jQuery 验证 - 仅指定 errorPlacement

javascript - 使用递归的加权作业调度

c++ - 两个已排序数组的交集

algorithm - 在 Matlab 中彻底排列大小为 20 的向量

java - 如何使用冒泡排序对任何通用集合进行排序并检查它是否已排序?

javascript - 重构对象数组

javascript - 有没有办法使用 MySQL 函数从 Lat、Lng 获取 POINT 坐标?

arrays - 找出比较两个项目的概率。 (请提示)

python - 按另一个数组的列对一个数组进行排序 - Python