不幸的是,你不能。
主要原因是 24 位 RGB 包含 16,777,216 种颜色 (256 3 )。只是为了得到一个估计,您将需要一个 4096 x 4096 像素的屏幕分辨率(当然没有这样的方形屏幕,但对于实际显示器来说,等效屏幕的格式约为 16:9)。
简单地说:在普通屏幕上没有空间放置所有像素。
此外,使用渐变会遇到问题,因为这仅适用于画布的一个方向。您需要在两个方向上绘制颜色,您需要直接手动操作位图。
我的建议是对现有的此类调色板进行屏幕快照并将该图像绘制到画布上。这将量化颜色(这也发生在所有可用的颜色选择器中),但会给你一个接近你需要的颜色的近似值。
另外你可以添加滑块来微调值以及文本框(后者在纯画布中有点复杂,但你可以结合html和画布来实现)。
表示“所有”颜色的近似值可能是这样的(来自下面演示的快照):
更新
好的,我保证会回复您关于根据 RGB 值计算位置的问题。从图像中的调色板开始,您可以通过将颜色转换为 HSV 颜色空间来轻松计算位置。
将 RGB 转为 HSV 的函数如下所示:
function rgb2hsv() {
var rr, gg, bb,
r = arguments[0] / 255,
g = arguments[1] / 255,
b = arguments[2] / 255,
h, s,
v = Math.max(r, g, b),
diff = v - Math.min(r, g, b),
diffc = function (c) {
return (v - c) / 6 / diff + 1 / 2;
};
if (diff === 0) {
h = s = 0;
} else {
s = diff / v;
rr = diffc(r);
gg = diffc(g);
bb = diffc(b);
if (r === v) {h = bb - gg}
else if (g === v) {h = (1 / 3) + rr - bb}
else if (b === v) {h = (2 / 3) + gg - rr};
if (h < 0) {h += 1}
else if (h > 1) {h -= 1}
}
return {
h: (h * 360 + 0.5) |0,
s: (s * 100 + 0.5) |0,
v: (v * 100 + 0.5) |0
}
};
现在颜色以度数 (0-359)、饱和度 (0-100) 和亮度 (0-100) 表示。
要获得水平位置,您需要做的就是将调色板的宽度除以 360 并乘以 h(色调)。要获得垂直位置,您将调色板分为上部和下部。如果饱和度 < 100 那么你在上半部分,如果 V < 100 那么你在下半部分:
function getPos(canvas, h, s, v) {
var m = canvas.height / 2,
x = canvas.width / 360 * h,
y;
if (s === 100 && v === 100) {
y = m;
} else if (v === 100 && s < 100) {
y = m / 100 * s;
} else if (s === 100 && v < 100) {
y = m / 100 * (100 - v) + m;
}
x = (x + 0.5) |0; //convert to integer
y = (y + 0.5) |0;
};
这当然需要您生成的调色板非常准确。
演示
请注意,光标不是根据鼠标位置设置的,而是根据 RGB (HSV) 值设置的。它首先从鼠标位置选择颜色 RGB,然后将其转换为 HSV 并从中计算位置。
调色板是根据窗口大小动态生成的。
同样值得一提的是,对于纯色选择,看起来平滑的渐变的问题在于它们是抖动的。这意味着您可以获得一个明显不在您选择范围内的像素值。
为了在您进行颜色选择时减少此问题,您需要平均从鼠标获得的 x 和 y 位置周围的区域。