I'm trying to draw the following gradient image in canvas, but there's a problem in the right bottom.
Desired effect:
Current output:
I'm probably missing something really simple here.
function color(r, g, b) {
var args = Array.prototype.slice.call(arguments);
if (args.length == 1) {
args.push(args[0]);
args.push(args[0]);
} else if (args.length != 3 && args.length != 4) {
return;
}
return "rgb(" + args.join() + ")";
}
function drawPixel(x, y, fill) {
var fill = fill || "black";
context.beginPath();
context.rect(x, y, 1, 1);
context.fillStyle = fill;
context.fill();
context.closePath();
}
var canvas = document.getElementById("primary");
var context = canvas.getContext("2d");
canvas.width = 256;
canvas.height = 256;
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.height; y++) {
var r = 255 - y;
var g = 255 - x - y;
var b = 255 - x - y;
drawPixel(x, y, color(r, g, b));
}
}
#primary {
display: block;
border: 1px solid gray;
}
<canvas id="primary"></canvas>




Using gradients.
You can get the GPU to do most of the processing for you.The 2D composite operation
multiplyeffectively multiplies two colours for each pixel. So for each channel and each pixelcolChanDest = Math.floor(colChanDest * (colChanSrc / 255))is done via the massively parallel processing power of the GPU, rather than a lowly shared thread running on a single core (JavaScript execution context).The two gradients
One is the background White to black from top to bottom
var gradB = ctx.createLinearGradient(0,0,0,255); gradB.addColorStop(0,"white"); gradB.addColorStop(1,"black");The other is the Hue that fades from transparent to opaque from left to right
var swatchHue var col = "rgba(0,0,0,0)" var gradC = ctx.createLinearGradient(0,0,255,0); gradC.addColorStop(0,``hsla(${hueValue},100%,50%,0)``); gradC.addColorStop(1,``hsla(${hueValue},100%,50%,1)``);Note the above strings quote are not rendering correctly on SO so I just doubled them to show, use a single quote as done in the demo snippet.
Rendering
Then layer the two, background (gray scale) first, then with composite operation "multiply"
Only works for Hue
It is important that the color (hue) is a pure colour value, you can not use a random rgb value. If you have a selected rgb value you need to extract the hue value from the rgb.
The following function will convert a RGB value to a HSL colour
Put it all together
The example renders a swatch for a random red, green, blue value every 3 second.
Note that this example uses Balel so that it will work on IE
To calculate the colour from the x and y coordinates you need the calculated Hue then the saturation and value to get the hsv colour (NOTE hsl and hsv are different colour models)
Function to get r,g,b values for h,s,v colour.