Arif Billah
Arif Billah

Reputation: 196

rgba() is producing a blackish tone in HTML5 Canvas Gradient

I wanted to draw three gradients on top of the other on a HTML5 Canvas. But it wasn't not producing the desired effect. So I dug into the thing a little bit, and found out that rgba(0, 0, 0, 0) was not completely transparent when used in canvas gradient. Rather it was producing an unexpected blackish tone.

In CSS, it works fine though.

How can I have the same effect as it works in CSS? (see attached screenshot please)

CSS properties:

background: linear-gradient(rgba(0, 0, 0, 0), rgb(255, 0, 0));

Canvas properties:

var grad = ctx.createLinearGradient(0, 0, 0, height);
    grad.addColorStop(0, 'rgba(0, 0, 0, 0)');
    grad.addColorStop(1, 'rgb(255, 0, 0)');

rgba() in CSS vs HTML5 Canvas

Upvotes: 1

Views: 370

Answers (1)

Kaiido
Kaiido

Reputation: 137016

Indeed the algorithms seem to be different.

Not quite sure why, but I'd say that CSS doesn't consider rgba(0,0,0,0) as transparent black pixel like canvas does, but instead just as transparent.

The 2D canvas will composite straight from all the 4 RGBA channels values, until the ones of the next stop, while CSS one seems to comprehend transparent as a particular case.

To get the same result as CSS on a canvas, you'd have to set your first transparent stop to the next one, by only changing the alpha value:

var ctx = c.getContext('2d'),
  grad = ctx.createLinearGradient(0,0,0,150);
grad.addColorStop(0, 'rgba(255,0,0,0)'); // transparent red
grad.addColorStop(1, 'rgba(255,0,0)');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,150);
#html{
  background: linear-gradient(rgba(0, 0, 0, 0), rgb(255, 0, 0));
  height: 150px;
  width: 300px;
  display: inline-block;
}
<div id="html"></div>
<canvas id="c"></canvas>

Upvotes: 2

Related Questions