使用 HTML5 画布为颜色选择创建渐变(所有可能的 RGB 颜色) [英] Create gradient for color selection with HTML5 canvas (all possible RGB colors)

查看:32
本文介绍了使用 HTML5 画布为颜色选择创建渐变(所有可能的 RGB 颜色)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以为线性颜色选择器增加包含所有可能的 RGB 颜色(只有红色、绿色、蓝色 - 没有 alpha 值)的线性渐变.

Is it possible to greate a linear gradient which contains all possible RGB colors (only red, green, blue - no alpha values) for a linear color picker.

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

So far I've tried it with the following gradient, but it doesn't contain all values from rgb(0,0,0) to rgb(255,255,255) :

var grd = ctx.createLinearGradient(0, 0, width, 0);
grd.addColorStop(0,     'red');
grd.addColorStop(1 / 6, 'orange');
grd.addColorStop(2 / 6, 'yellow');
grd.addColorStop(3 / 6, 'green')
grd.addColorStop(4 / 6, 'aqua');
grd.addColorStop(5 / 6, 'blue');
grd.addColorStop(1,     'purple');

非常感谢任何帮助.

推荐答案

很遗憾,你不能.

主要原因是 24 位 RGB 包含 16,777,216 种颜色(2563).只是为了估算一下,您将需要一个 4096 x 4096 像素的屏幕分辨率(当然没有这样的方形屏幕,但对于实际显示器而言,其等效格式约为 16:9).

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).

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

Simply put: there is no room to place all the pixels on a normal screen.

此外,您会遇到使用渐变的问题,因为这仅在画布的一个方向上进行.您需要在两个方向上绘制颜色,您需要直接手动操作位图.

In addition you will get problem using a gradient as this goes only in one direction for canvas. You would need to plot the color in two directions which you need to do manually manipulating the bitmap directly.

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

My suggestion is to take a screen snapshot of an existing such palette and draw that image onto the canvas. This will quantize the colors (this also happens in all available color pickers) but will give you a close approximation to the color you need.

另外你可以添加滑块来微调值以及文本框(后者在纯canvas中有点复杂,但你可以通过html和canvas的组合来实现).

In addition you can add sliders to fine-adjust the value as well as text boxes (the latter is a bit complicated in pure canvas, but you can make a combination of html and canvas to achieve this).

表示所有"颜色的近似值可能是这样的(来自下面演示的快照):

An approximation representing "all" colors could be like this (snapshot from demo below):

更新

好的,我保证会回复您关于根据 RGB 值计算位置的问题.从图像中的调色板开始,您可以通过将颜色转换为 HSV 颜色空间来轻松计算位置.

Ok, I promised to get back to you about calculating the position from a RGB value. Starting in a palette as in the image you can easily calculate the position by converting the color to HSV color space.

将 RGB 转为 HSV 的函数如下所示:

The function to do RGB to HSV looks like this:

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) 表示.

Now color is represented in degrees (0-359), saturation (0-100) and luminance (0-100).

要获得水平位置,您需要做的就是将调色板的宽度除以 360 并乘以 h(色调).要获得垂直位置,您将调色板分为上部和下部.如果饱和度 <100 那么你在上半部分,如果 V <<100 那么你在下半部分:

To get horizontal position all you need to do is to divide width of your palette on 360 and multiply with h (hue). To get vertical position you split the palette in upper part and lower part. If saturation is < 100 then you're in the upper part, if V < 100 then you're in lower part:

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;

};

这当然要求您生成的调色板非常准确.

This will of course require that the palette you generate is very accurate.

演示

请注意,光标不是根据鼠标位置设置的,而是根据 RGB (HSV) 值设置的.它首先从鼠标位置选择颜色 RGB,然后将其转换为 HSV 并从中计算位置.

Notice the cursor is not set based on mouse position, but on RGB (HSV) value. It first picks a color RGB from mouse position, then converts it to HSV and calculate the position from that.

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

The palette is generated dynamically in relation to window size.

对于纯色的选择,还值得一提的是,看起来平滑的渐变的问题在于它们是抖动的.这意味着您可以获得明显不在您选择范围内的像素值.

Also worth to mention for plain color picking, is that the problem with gradients that seems smooth is that they are dithered. This means that you can get a pixel value that apparently is not in the range you're picking from.

为了在您选择颜色时减少此问题,您需要平均从鼠标获得的 x 和 y 位置周围的区域.

To reduce this problem when you do a color pick, you will need to average the area around the x and y position you get from the mouse.

这篇关于使用 HTML5 画布为颜色选择创建渐变(所有可能的 RGB 颜色)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆