Canvas 使用HTML5画布为颜色选择创建渐变(所有可能的RGB颜色)

Canvas 使用HTML5画布为颜色选择创建渐变(所有可能的RGB颜色),canvas,colors,html5-canvas,gradient,color-space,Canvas,Colors,Html5 Canvas,Gradient,Color Space,对于线性颜色选择器,是否可以将包含所有可能RGB颜色(仅红色、绿色、蓝色-无alpha值)的线性渐变变大 到目前为止,我已经尝试使用以下渐变,但它不包含从rgb(0,0,0)到rgb(255255)的所有值: 非常感谢您的帮助。不幸的是,您不能 主要原因是24位RGB包含16777216种颜色(2563)。为了得到一个估计值,你需要一个4096 x 4096像素的屏幕分辨率(当然没有这样的方形屏幕,但是对于一个实际的显示器来说,等效的分辨率大约是16:9) 简单地说:在普通屏幕上没有空间放置所有

对于线性颜色选择器,是否可以将包含所有可能RGB颜色(仅红色、绿色、蓝色-无alpha值)的线性渐变变大

到目前为止,我已经尝试使用以下渐变,但它不包含从
rgb(0,0,0)
rgb(255255)
的所有值:


非常感谢您的帮助。

不幸的是,您不能

主要原因是24位RGB包含16777216种颜色(2563)。为了得到一个估计值,你需要一个4096 x 4096像素的屏幕分辨率(当然没有这样的方形屏幕,但是对于一个实际的显示器来说,等效的分辨率大约是16:9)

简单地说:在普通屏幕上没有空间放置所有像素

此外,使用渐变时会遇到问题,因为对于画布来说,渐变只朝一个方向移动。您需要在两个方向上绘制颜色,这需要直接手动操作位图

我的建议是对现有的调色板进行屏幕快照,并将该图像绘制到画布上。这将量化颜色(这也发生在所有可用的颜色选择器中),但将为您提供所需颜色的近似值

此外,您还可以添加滑块来微调值和文本框(纯画布中的文本框有点复杂,但您可以将html和画布结合起来实现这一点)

表示“所有”颜色的近似值可以如下所示(下面演示中的快照):

更新

好的,我答应过会回复你关于用RGB值计算位置的问题。从图像中的调色板开始,通过将颜色转换为HSV颜色空间,可以轻松计算位置

对HSV执行RGB的功能如下所示:

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
    }
};
函数rgb2hsv(){
风险值rr,gg,bb,
r=参数[0]/255,
g=参数[1]/255,
b=参数[2]/255,
h、 s,
v=数学最大值(r,g,b),
微分=v-数学最小值(r,g,b),
diffc=函数(c){
返回(v-c)/6/diff+1/2;
};
如果(差异===0){
h=s=0;
}否则{
s=diff/v;
rr=diffc(r);
gg=diffc(g);
bb=diffc(b);
如果(r==v){h=bb-gg}
如果(g==v){h=(1/3)+rr-bb}
如果(b==v){h=(2/3)+gg-rr};
如果(h<0){h+=1}
如果(h>1){h-=1}
}
返回{
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,则位于上部;如果饱和度小于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;

};
函数getPos(画布、h、s、v){ var m=画布高度/2, x=canvas.width/360*h, Y 如果(s==100&&v==100){ y=m; }否则如果(v==100&&s<100){ y=m/100*s; }如果(s===100&&v<100),则为else{ y=m/100*(100-v)+m; } x=(x+0.5)| 0;//转换为整数 y=(y+0.5)| 0; }; 这当然需要生成的调色板非常精确

请注意,光标不是基于鼠标位置设置的,而是基于RGB(HSV)值设置的。它首先从鼠标位置拾取一个颜色RGB,然后将其转换为HSV并根据该值计算位置

调色板是根据窗口大小动态生成的

同样值得一提的是,对于素色拾取,渐变看起来平滑的问题在于它们抖动。这意味着您可以获得一个像素值,该值显然不在您选择的范围内


要在进行颜色拾取时减少此问题,您需要平均从鼠标获得的x和y位置周围的区域。

+1 Philipp是正确的。RGB颜色在2d空间中无法很好地表示,因为RGB有3个组件,所有组件都必须表示

最接近几何表示所有rgb组合的是立方体(因为立方体有3个轴,而rgb有3个值)

以下是维基百科的一个例子:


您可以将此作为起点,并使用滑块从前到后显示每种颜色的“层”。

您可能想问自己,您想用这些颜色做什么,以及为什么。此外,您可能会考虑您将拥有的用户类型以及他们想用这些颜色做什么。

正如其他响应者所指出的,RGB颜色空间是三维的。但绘制这三个维度的方法不止一种。还有色调/饱和度/值(HSV)。许多带有颜色选择器的应用程序都有这两个选项,并排或在单独的选项卡中

HSV中的H色调可以被认为是沿着彩虹的位置,从红色开始,再次循环回到红色。这通常表示为沿圆的位置,红色表示为0度/360度,绿色表示为120度,蓝色表示为240度

饱和度是指“颜色中有多少颜色”,100%的饱和度表示全色,0%的饱和度表示单色黑、白、灰。值表示颜色的亮度或暗度,对于任何色调,0%的值为黑色
#000000
,100%的值为全亮度,如果饱和度也为100%,则该色调的全颜色

下面是Gimp颜色选择器的屏幕截图。您可以看到,它有色相、饱和度和值的滑块,在红色、绿色和蓝色的滑块之上

色调的值范围为0到359度(饱和度)
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;

};