Javascript Canvas fillRect transparent black - javascript

I'm developing a resource monitor with JavaScript, and I pretend to complete it with an cool background animation.
I'm having trouble with fillRect and transparent colors in fillStyle, eg.:
function draw() {
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "#00FF00";
ctx.strokeStyle = "#00FF00";
ctx.beginPath();
ctx.arc(getRandom(0, c.width),getRandom(0,c.height),25,0,2*Math.PI);
ctx.arc(getRandom(0, c.width),getRandom(0,c.height),25,0,2*Math.PI);
ctx.stroke();
}
It works fine, but it doesn't fill completely, leaving some "ghosts" where circles already passed before.
There is anyway to fix this and make background pure black again?
Notes:
I can't draw pure black, because I want the drawed lines smoothly disappear
Image of the problem: http://i.stack.imgur.com/GrPxX.png
Note that yellow dots are most recent lines, orange are transitional lines, which give the smooth effect, and red dot are the "ghosts"

When you fill the rectangle, you're using a semi-transparent black. What that will do is to darken what's there, but it won't obliterate it, because it's semi-transparent. If you want to cover it up with pure black, either set full opacity (max alpha value), or else use an rgb colour rather than rgba. If you use rgb, the alpha value will implicitly be set to opaque.

Related

Can not change the background to white in the Canvas animation

I found a Canvas animation that fits my site, but I can't remove the background from it (or replace it with white) when replacing the background with a light one, the animation disappears immediately.
I'm just starting to get acquainted with Canvas, so do not swear much.
Here is a normal background (line 162): https://codepen.io/obiwan-kenobi/pen/vQyBxP
drawGradient ({ctx, canvas, bounds}) {
ctx.fillStyle = '# 252f3d';
ctx.fillRect (... bounds.params); }
But with white (I made it gray so that the animation could be seen, but on white there are none at all, line 162): https://codepen.io/obiwan-kenobi/pen/GwNKYg
drawGradient ({ctx, canvas, bounds}) {
ctx.fillStyle = '# e2e1e1';
ctx.fillRect (... bounds.params); }
the example you posted uses a particular compositing operation named "screen" that always result in a lighter color. Since there is no lighter color than white all shapes are invisible on a white background.
To solve your specific problem you may change the value of this property from "screen" to "multiply" and your background to white:
// row #162
ctx.fillStyle = '#FFFFFF';
/// .....
// row #450:
ctx.globalCompositeOperation = 'multiply';
Demo
All available values for this property can be found here --> globalCompositeOperation reference

Can I fill a rectangle with a transparent gradient javascript canvas?

I'm trying to overlay this black rectangle:
By filling another rectangle of the same size on top of it that has a semi-transparent, gradient paint (should look something like this):
I know I can do a transparent paint with the following:
g2d.fillStyle = "rgba(100, 3, 3, 0.5)";
I also know how to do a gradient paint:
var grd=g2d.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"blue");
g2d.fillStyle=grd;
However, I do not know how to combine both the gradient and transparency properties together as one paint to use on my rectangle. How can I do this?
There are two ways:
Global alpha
Set global (consider it a "master alpha") right before drawing something:
ctx.globalAlpha = 0.5; // [0, 1]
ctx.fillRect( ... );
Color alpha
Or define the colors themselves with alphas:
grd.addColorStop(0, "rgba(255,0,0, 0.5)"); // 50% alpha
grd.addColorStop(1, "rgba(0,0,255, 0.5)");
Worth to notice: if you use the latter approach and for example set 0% opacity on one end, the color will still matter as it is interpolated to the point where it becomes fully transparent. In the meanwhile the color definition will bleed through. I.e. don't just set black (unless black is what you need).
First draw the gradient:
var grd=g2d.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"blue");
g2d.fillStyle=grd;
Then draw the semi-transparent background:
g2d.fillStyle = "rgba(200,0,0,0.5)";
g2d.fillRect(x,y,w,h);

Re-draw transparent background on canvas

I have a canvas with a transparent background.
After drawing some content, I want to erase part of it and go back to the transparent background.
Simply drawing on top of the content to be erased with
fillStyle = rgba(0, 0, 0, 0);
does not do anything, since transparent on top of a color = color.
Is there a mode that sets subsequent drawings to "replace content at this position"?
you can use the clearRect function
context.clearRect(x, y, width, height)
see this http://jsfiddle.net/5g87J/
Your best (and probably only) option is .clearRect(x, y, w, h) to delete part of the canvas.

How would you create a gradient solely with Javascript (no css) that goes from black to white?

Any help? I am new to Javascript. It is just an interesting question I saw online and I am curious possible solutions.
Thanks!
An example using canvas:
var
canvas = document.getElementById('gradient'),
context = canvas.getContext('2d'),
gradient = context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, '#ffffff');
gradient.addColorStop(1, '#000000');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
(demo)
Or by filling the DOM with elements: http://jsfiddle.net/UYxs7/1 (technically this is CSS)
Well black is the hex value #000000 and white the value #FFFFFF, to make things easier we can represent this in decimal values as RGB (0,0,0) and RGB (255,255,255).
You can then use a multitude of approaches varying the colour value as you go in equal amount between R G and B creating a range of gray scale colours.
You could do this on a canvas, you could even do it using a div for each pixel, or you could just use an image if CSS isn't an option. Using divs per pixel is an option but in my opinion really not a very good one.
Pseudo code:
for i = 0 to 255 {
create div 1/255th of the height of the container and set its background colour to RGB(i,i,i)
}
The problem with this is you will still have to use CSS since styling a DIV can not be done without.
The only possible way to do it completely without CSS would be to use images. If you wanted to dynamically create gradients using images you could even go as far as having images for each grayscale colour and using these in img tags. Again you would not be able to use background images etc since this is CSS too.

Identical calls to arc producing different sizes

I'm trying to figure out why drawing a shape, then drawing over it in a new color (as though to highlight it), and then re-drawing the original (un-highlighting it) is leaving traces of the highlighted color.
I've reproduced the issue in this fiddle. The wedge is drawn in a light-blue color. There's a red button that'll draw over it in red, then another button that re-draws the original shape. All parameters are identical (except for the color), but yet after clicking the button to reset the color, there's a faint trace of red over the wedge.
Before:
After:
Here's the relevant code:
drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");
$("#red").click(function () {
drawWedge(250, 250, 200, 0, 18, "rgb(255, 0, 0)");
});
$("#back").click(function () {
drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");
});
function d2r(degrees) {
return degrees * (Math.PI / 180.0);
}
function drawWedge(centerX, centerY, r, start, end, color) {
context.beginPath();
context.moveTo(centerX, centerY);
context.arc(centerX, centerY, r, d2r(start), d2r(end), false);
context.closePath();
context.fillStyle = color;
context.fill();
}
This question was already answered, but I wanted to give a little more thorough explanation.
When you draw at a diagonal, your passing through "parts" of pixels (show in my example). So what does the browser do to the part of the pixel outside of the shape? It uses anti-aliasing (anti-aliasing is always on by default for browsers) to color the rest of the pixel (if you didnt have anti-aliasing the line would look jagged). If you notice, the faint trace of red is not a bright red because its getting blended due to anti-aliasing. And the reason you see it is because when you draw your shape on the canvas, the faint trace of red is not part of your shape, its part of the pixel on the outside of your shape.
Now as the answer mentioned, you can call clearRect to clear the canvas. However, you should read this SO question as it explains things in more detail (the selected answer is not as good as the second answer). Also, ever wonder why they call it a "canvas"? Think of an actual art canvas used by artists, once they paint on the canvas there is no way to take it off unless you get a new canvas or paint over it!
When drawing on canvas, it just keeps stacking things on top of each other until you clear it. The easiest way to clear it is ctx.clearRect(0,0,width,height)
I put that in your drawWedge function here:
http://jsfiddle.net/X7deh/1

Categories