Сортировать цвета в двух измерениях - PullRequest
0 голосов
/ 25 января 2019

Для нужд веб-проекта я хотел бы создать палитру цветов из списка определенных цветов. Вот что я сделал:

unsorted color picker

Как видите, цвета не отсортированы. Я нашел много алгоритмов для сортировки цветов, но не в 2D. Результат, который я хотел бы получить, выглядит примерно так:

sorted color picker

Ты хоть представляешь, что я могу сделать? Спасибо.

Если вам интересно, я уже видел этот пост , но проблема не та же: я еще не знаю окончательную позицию 50% цветов.

Вот предварительная сортировка по красному на оси X и зеленому на оси Y:

red green sorted color picker

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Вы можете преобразовать цвета из RGB в HSL, а затем отсортировать по оттенкам и насыщенности (например, x / y).

Чтобы упорядочить цвета, как на втором изображении, вы можете подумать, что оттенок находится на цветовом колесе, и преобразовать его в положение x / y, которое соответствует вашему квадрату или прямоугольнику.

В качестве альтернативы вы можете отсортировать по красному / зеленому (х / у), как уже упоминалось в комментариях (показанное вами дополнительное изображение не сортируется по красному / зеленому).

0 голосов
/ 27 января 2019

Спасибо за вашу помощь Danny_ds и Harsh Gupta .Я пытался сделать палитру цветов, которая была бы «грязной» на осях X и Y.Я пробовал дюжину различных алгоритмов, и это просто не выглядит хорошо.Итак, теперь я просто сортирую только по одной оси, а затем сортирую каждую строку.Результат выглядит очень хорошо:

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>
0 голосов
/ 25 января 2019

Второе изображение - это не просто матрица, в которой цвета каким-то образом отсортированы.На самом деле это часть трехмерной цветовой модели, рассматриваемая под углом.Цветовая модель - это визуализация, показывающая цветовой спектр в многомерных измерениях.Такие инструменты, как 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...