Как получить значение цвета из цветового круга на основе координат X & Y? - PullRequest
0 голосов
/ 11 октября 2018

Итак, у меня есть это цветовое колесо, которое будет использоваться для палитры цветов.
Я делаю это через NativeScript для мобильного приложения.И я хотел бы знать, как получить RGB или HEX (, поскольку я могу использовать либо ) с использованием только координат X / Y?

{x:0,y:0}это самый центр, поэтому отрицательные числа будут влево и вверх, а положительные числа влево и вправо.
Я застрял при попытке выяснить, как получить цвет.У меня нет кода для отображения, так как я не знаю, с чего начать.

Цветовое колесо - это предварительно созданное изображение, а не я автоматически генерирую его с помощью холста при каждом использовании приложения.

color wheel

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Все следующие угловые измерения основаны на обычном математическом смысле: 0 ° направлено горизонтально вправо, углы увеличиваются против часовой стрелки, поэтому 90 ° вверх, 180 ° влево и 270 ° вниз.

Используя цветовое колесо в MS PowerPoint (поскольку оно доступно), значения рассчитываются путем деления круга на 3 сегмента шириной 120 ° с центром в 0 °, 120 ° и 240 ° для красного, зеленого и синего соответственно.

На границах сегментов цвет составляет 100% смежных цветов, поэтому 60 ° - это 100% красный и 100% зеленый.Примыкающий цвет исчезает к центру сегмента, поэтому при 90 ° (на полпути от красной / зеленой границы к зеленому центру) цвет становится на 100% зеленым и на 50% красным.

Это даетсочетание смежных цветов, смешение противоположных цветов основано на расстоянии от центра.

Эта схема отображения не работает для RGB, так как это трехмерное пространство, однако оно дает 2 из 3 измеренийдля HSV, если координаты используются для оттенка и насыщенности и смежного ползунка для значения .Для простоты ниже просто используется диск со значением , установленным на 1.

Полное объяснение приведено на Ручное кодирование цветового круга с канвой .

/* Convert radians to degrees.
 *
 * @param {number} rad - radians to convert, expects
 *                       rad in range +/- PI per Math.atan2
 * @returns {number} degrees equivalent of rad
 */
function rad2deg(rad) {
  return (360 + 180 * rad / Math.PI) % 360;
}

/* Convert h,s,v values to r,g,b
 * See: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
 *
 * @param {number} hue - in range [0, 360]
 * @param {number} saturation - in range 0 to 1
 * @param {number} value - in range 0 to 1
 * @returns {Array|number} [r, g,b] in range 0 to 255
 */
function hsv2rgb(hue, saturation, value) {
  hue /= 60;
  let chroma = value * saturation;
  let x = chroma * (1 - Math.abs((hue % 2) - 1));
  let rgb = hue <= 1? [chroma, x, 0]:
            hue <= 2? [x, chroma, 0]:
            hue <= 3? [0, chroma, x]:
            hue <= 4? [0, x, chroma]:
            hue <= 5? [x, 0, chroma]:
                      [chroma, 0, x];

  return rgb.map(v => (v + value - chroma) * 255);
}

/* Convert cartesian coordinates to RGB
 * Converts: x, y to polar (radial_distance, angle), then
 *           polar to HSV, then
 *           HSV to RGB
 *
 * @param {number} x - x coordinate in range -1 to 1
 * @param {number} y - y coordinate in range -1 to 1
 * @returns {Array|number} [red, green, blue] values in range 0 to 255
 */
function rectToRGB(x, y) {
  // Hue is from angle, saturation from distance from centre, value set to 1
  var r = Math.sqrt(x*x + y*y);
  // Limit extent to disc
  var sat = r > 1? 0 : r;
  var hsv = [rad2deg(Math.atan2(y, x)), sat, 1];
  var rgb = hsv2rgb(...hsv).map(Math.round);
  return rgb;
}

function posToColour(evt) {
  var node = this;
  var originOffset = node.width / 2;
  var offsetLeft = offsetTop = 0;
  
  do {
    offsetLeft += node.offsetLeft;
    offsetTop  += node.offsetTop;
    node = node.offsetParent;
  } while (node.offsetParent)
    
  // Adjust coordinates then scale to range -1 to 1
  var x = ((evt.x - offsetLeft - originOffset) / originOffset).toFixed(2);
  var y = ((originOffset - evt.y + offsetTop) / originOffset).toFixed(2);

  var rgb = rectToRGB(x, y);
  
  var patch = document.getElementById('colorPatch');
  patch.style.backgroundColor = `rgb(${rgb.join()})`;
  document.getElementById('data').innerHTML = 
    `x, y : ${(x<0?'':' ')+x}, ${(y<0?'':' ')+y}<br>r,g,b: ${rgb.map(x=>('  '+x).slice(-3)).join(', ')}`;
}

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById('colourDisc').addEventListener('mousemove', posToColour, false);
}, false);
img {width:200px;height:200px;}
div {width: 90px; height: 90px}

 
   
image

Если вы создаете цветовое колесо как холст для связанной статьи,тогда, скорее всего, вы можете просто получить цвет под курсором.

hsv2rgb несколько уменьшен по сравнению с оригиналом, но я думаю, что он намного понятнее, поскольку он короче, поскольку существует риск чрезмерного использования:?оператор.

0 голосов
/ 11 октября 2018

Вы, похоже, исключаете некоторые детали, я предполагаю, что у вас уже есть метод транслятора координат или что-то в этом роде, я знаю, что у вас есть холст, следовательно, у вас есть холст api и данные изображения.

function getRGB(x, y, canvas) {
  let context = canvas.getContext('2d');
  let [red, green, blue, alpha] = context.getImageData(x, y, 1, 1).data;
  return {red, green, blue, alpha};
} 
0 голосов
/ 11 октября 2018

Простой способ получить цвета с этого колеса - это получить его как Hsl, а затем преобразовать его в RGB (или Hex). Значения оттенка и насыщенности легко определяются по кругу, tan (hue) = y / x;оттенок = оттенок% 360 // насыщенность = √ (x² + y²) * 100 / радиус.но значение яркости не может быть определено на картинке, поэтому я бы выбрал 50%.

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