所以我有这个色轮,它将用于拾色器。
我正在通过NativeScript针对移动应用程序进行此操作。而且我想知道如何仅使用X / Y坐标获得RGB 或十六进制(,因为我可以使用任何一个)?
{x:0,y:0}
的正中央,因此负数将在左侧和上方,而正数在右侧和向下。
我坚持试图弄清楚如何获得颜色。我没有要显示的代码,因为我不知道从哪里开始。
色轮是预制的图像,而不是在使用该应用程序时由我自动用画布生成的图像。
答案 0 :(得分:2)
以下所有角度度量均基于通常的数学意义:0°沿水平方向向右倾斜,因此角度沿逆时针方向增加,因此90°向上,向左180°,向下270°。
使用MS PowerPoint中的色轮(因为它可用),通过将圆分成3个120°宽的部分(分别以红色,绿色和蓝色的0°,120°和240°为中心)来计算值。
在线段边界上,颜色是相邻颜色的100%,因此60°是100%红色和100%绿色。相邻的颜色逐渐淡入分段的中心,因此在90°(从红色/绿色边界向绿色中心的一半距离)处,颜色为100%绿色和50%红色。
这给出了相邻颜色的混合,相反颜色的混合是基于距中心的距离。
此映射方案不适用于RGB,因为它是3维空间,但是如果将坐标用于 hue 和饱和度,则它会给出3个HSV维中的2个和 value 的相邻滑块。为简单起见,以下仅使用 value 设置为1的光盘。
完整的解释在Hand-coding a color wheel with canvas。
/* 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}
<table>
<tr>
<td><img src="https://i.stack.imgur.com/lPPOO.png" id="colourDisc"></td>
<td><div id="colorPatch"></div>
<div><pre id="data"></pre></div></td>
</table>
如果您根据链接的文章将色轮生成为画布,那么很可能只需在光标下找到颜色即可。
hsv2rgb 相对于原始版本略有缩小,但是我认为它更短更清楚,但有过度使用:?的危险。运算符。
答案 1 :(得分:0)
您似乎要排除一些细节,我假设您已经有一个坐标转换方法或其他东西,我知道您有一个画布,因此您具有画布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};
}
答案 2 :(得分:-1)
从此轮获取颜色的简单方法是将其获取为Hsl,然后将其转换为RGB(或十六进制)。色相和饱和度值很容易从圆上确定tan(hue)= y / x;色相=色相%360 //饱和度=√(x²+y²)* 100 /半径。但是亮度值无法从图片中确定,因此我会选择50%。