不幸的是,不,你不能。
The main reason is that 24-bit RGB contains 16,777,216 number of colors (2563). Just to get an estimate you will will need a screen resolution that is 4096 x 4096 pixels (of course there is no such square screen, but the equivalent would be in about 16:9 format of that for an actual monitor).
简而言之:普通屏幕上没有空间放置所有像素。
此外,使用渐变时会遇到问题,因为渐变仅在画布的一个方向上进行。您需要在两个方向上绘制颜色,您需要直接手动操作位图。
我的建议是拍摄现有此类调色板的屏幕快照并将该图像绘制到画布上。这将量化颜色(这也会发生在所有可用的颜色选择器中),但会给您一个接近您需要的颜色。
此外,您还可以添加滑块来微调值以及文本框(后者在纯canvas中有点复杂,但您可以将html和canvas结合起来来实现这一点)。
代表“所有”颜色的近似值可能如下所示(下面演示的快照):
Update
好的,我答应会回复您有关根据 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(色调)。为了获得垂直位置,您将调色板分为上部和下部。如果饱和度
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;
};
这当然要求您生成的调色板非常准确。
Demo
请注意,光标不是根据鼠标位置设置的,而是根据 RGB (HSV) 值设置的。它首先从鼠标位置选取 RGB 颜色,然后将其转换为 HSV 并据此计算位置。
调色板是根据窗口大小动态生成的。
对于纯色拾取还值得一提的是,看起来平滑的渐变的问题是它们会抖动。这意味着您可以获得显然不在您选择范围内的像素值。
为了在进行颜色选择时减少此问题,您需要对从鼠标获得的 x 和 y 位置周围的区域进行平均。