HTML5 - Change opacity of a draw Rectangle - html

Let's say I draw an HTML5 element of rectangle using this:
context.clearRect(25, 72, 32, 32);
How would I make it 50% transparent?

Use globalAlpha. You'll also have to draw with fillRect. clearRect just erases pixels. It can't partially erase so you'll have to use fillRect or other drawing primitives.
from w3schools.com:
ctx.globalAlpha = 0.2;
ctx.fillRect(50,50,75,50);
ctx.globalAlpha = 1.0;

ClearRect removes what was there and leaves it blank. The best way is to use a rgba fillStyle value as it will only make the rectangle (or any other shape that you are drawing) transparent. The code would be:
ctx.fillStyle = 'rgba(225,225,225,0.5)';
ctx.fillRect(25,72,32,32);
(thanks How to change the opacity (alpha, transparency) of an element in a canvas element after it has been drawn?)

Related

clearRect with fade to transparent

I've drawn some shapes to my transparent canvas.
Lots of animated circles to be precise.
I would like to fade the bottom edge of my canvas to fully transparent, from transparent (but with the shapes).
Edit
See the image below; I'm after the effect on the right, as opposed to what I currently have which is a cut in half circle using clearRect()
Anyone have an ideas?
You can create a gradient with alpha in it (using rgba() syntax) and apply it to the stroke. Something like:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0,"#f00");
gradient.addColorStop(0.75,"rgba(255, 0, 0, 0)");
ctx.strokeStyle = gradient;
ctx.lineWidth = 10;
ctx.beginPath();
ctx.arc(150, 150, 100, 0, Math.PI * 2);
ctx.stroke();
Here's a quick demo for it: http://codepen.io/codingcampbell/pen/wMeowa
Changing the 0.75 value in addColorStop is what would affect where the alpha part of the gradient comes in. Animating it might be tricky, I think you need to create a new gradient for each stop value because you can't modify existing stops (but you can keep those gradients in memory and share them with all your shapes)
The easiest way would be to make a small vertical gradient and apply it as an eraser on the full circle. To make the effect that it's being animated, just move it upwards on every frame (and start from below the circle).

Draw stroke on HTML canvas with different levels of opacity

The problem
I'm trying to create a brush tool with opacity jitter (like in Photoshop). The specific problem is:
Draw a stroke on an HTML canvas with different levels of opacity. Pixels with higher opacity should replace pixels with lower opacity; otherwise, pixels are left unchanged.
Transparency should not be lost in the process. The stroke is drawn on a separate canvas and merged with a background canvas afterwards.
The result should look like this. All code and the corresponding output can be found here (JSFiddle).
Because you can't stroke a single path with different levels of opacity (please correct me if I'm wrong) my code creates a path for each segment with different opacity.
Non-solution 1, Using the 'darken' blend mode
The darken blend mode yields the desired result when using opaque pixels but doesn't seem to work with transparency. Loosing transparency is a dealbreaker.
With opaque pixels:
With transparent pixels:
Non-solution 2, Using the 'destination-out' compositing operator
Before drawing a new stroke segment, subtract its opacity from subjacent pixels by using the 'destination-out' compositing operator. Then add the new stroke segment with 'source-over'. This works almost but it's a little bit off.
Looking for a solution
I want to avoid manipulating each pixel by hand (which I have done in the past). Am I missing something obvious? Is there a simple solution to this problem?
"Links to jsfiddle.net must be accompanied by code."
Because you can't stroke a single path with different levels of opacity (please correct me if I'm wrong)
You're wrong =)
When you use globalCompositeOperation = 'destination-out' (which you are in lineDestinationOut) you need to set the strokeStyle opacity to 1 to remove everything.
However, simply changing that in your fiddle doesn't have the required effect due to the order of your path build. Build the 10% transparent one first, the whole length, then delete and draw the two 40% transparent bits.
Here's a jsfiddle of the code below
var canvas = document.getElementById('canvas');
var cx = canvas.getContext('2d');
cx.lineCap = 'round';
cx.lineJoin = 'round';
cx.lineWidth = 40;
// Create the first line, 10% transparency, the whole length of the shape.
cx.strokeStyle = 'rgba(0,0,255,0.1)';
cx.beginPath();
cx.moveTo(20,20);
cx.lineTo(260,20);
cx.lineTo(220,60);
cx.stroke();
cx.closePath();
// Create the first part of the second line, first by clearing the first
// line, then 40% transparency.
cx.strokeStyle = 'black';
cx.globalCompositeOperation = 'destination-out';
cx.beginPath();
cx.moveTo(20,20);
cx.lineTo(100,20);
cx.stroke();
cx.strokeStyle = 'rgba(0,0,255,0.4)';
cx.globalCompositeOperation = 'source-over';
cx.stroke();
cx.closePath();
// Create the second part of the second line, same as above.
cx.strokeStyle = 'black';
cx.globalCompositeOperation = 'destination-out';
cx.beginPath();
cx.moveTo(180,20);
cx.lineTo(260,20);
cx.stroke();
cx.strokeStyle = 'rgba(0,0,255,0.4)';
cx.globalCompositeOperation = 'source-over';
cx.stroke();
cx.closePath();
Use two layers to draw to:
First calculate the top layer opacity 40% - 10% and set this as alpha on top layer
Set bottom layer to 10%
Set top layer with dashed lines (lineDash) (calculate the dash-pattern size based on size requirements)
Draw lines to both layers and the bottom layer will be a single long line, the top layer will draw a dashed line on top when stroked.
Copy both layers to main canvas when done.
#HenryBlyth's answer is probably the best you're going to get; there's no native API to do what you're being asked to do (which, in my opinion, is kinda weird anyways... opacity isn't really supposed to replace pixels).
To spell out the solution in one paragraph: Split up your "stroke" into individual paths with different opacities. Draw the lowest opacity paths as normal. Then, draw the higher opacities with "desitination-out" to remove the low-opacity paths that overlap. Then, draw the high opacity paths as usual, with "source-over", to create the effect desired.
As suggested in the comments to that answer, #markE's comment about making each path an object that is pre-sorted before drawing is a great suggestion. Since you want to perform manual drawing logic that the native API can't do, turning each path into an object and dealing with them that way will be far easier than manually manipulating each pixel (though that solution would work, it could also drive you mad.)
You mention that each stroke is being done on another canvas, which is great, because you can record the mouseevents that fire as that line is being drawn, create an object to represent that path, and then use that object and others in your "merged" canvas without having to worry about pixel manipulation or anything else. I highly recommend switching to an object-oriented approach like #markE suggested, if possible.

Canvas fillStyle none in HTML5

I want to fill no color to canvas i.e. I want the background div color should keep on displaying in the div. I have googled it but didn't find any solution to keep fillStyle as no color.
Also I tried omitting the fillStyle but it leave me with black color.
Any options available?
Thanks
You need to use this to clear the canvas:
context.clearRect(0, 0, canvas.width, canvas.height);
(or the rectangle you need).
Also make sure you have no CSS rules set for the canvas element's background (which might be the case if your canvas is not transparent on init as canvas is transparent as default).
If you need to clear a non-regular shape you can use composite mode:
context.globalCompositeOperation = 'destination-out';
(xor and source-out can also be used too to a certain degree too to remove existing pixels but with some variations).
This will clear the canvas in the form of the next shape (Path) you draw (or use an image which solid pixels will clear the canvas).
I don't know what you're trying to do, but it seems you want to make your canvas transparent. You could do that in JavaScript:
context.fillStyle = "rgba(0, 0, 200, 0)";
Or in CSS, where foo would be the id of the canvas element. Note that this would make the element per se transparent, not just it's contents.
#foo {
opacity: 0;
}
You need to clear your canvas, not draw transparency... just think about that. You can't clean a glass, by using clear paint, the same is applied to the <canvas> element.
http://jsfiddle.net/Z6XTg/1/
this canvas demo does a very simple
ctx.clearRect(0,0,canvas.width,canvas.height);
before it draws anything, thus maintaining the canvas transparency.

How do I make a transparent canvas in html5?

How can I make a canvas transparent? I need to because I want to put two canvases on top of one another.
Canvases are transparent by default.
Try setting a page background image, and then put a canvas over it. If nothing is drawn on the canvas, you can fully see the page background.
Think of a canvas as like painting on a glass plate.
To clear a canvas after having drawn on it, just use clearRect:
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
I believe you are trying to do exactly what I just tried to do:
I want two stacked canvases... the bottom one has a static image and the top one contains animated sprites. Because of the animation, you need to clear the background of the top layer to transparent at the start of rendering every new frame. I finally found the answer: it's not using globalAlpha, and it's not using a rgba() color. The simple, effective answer is:
context.clearRect(0,0,width,height);
Iif you want a particular <canvas id="canvasID"> to be always transparent you just have to set
#canvasID{
opacity:0.5;
}
Instead, if you want some particular elements inside the canvas area to be transparent, you have to set transparency when you draw, i.e.
context.fillStyle = "rgba(0, 0, 200, 0.5)";
Just set the background of the canvas to transparent.
#canvasID{
background:transparent;
}
Paint your two canvases onto a third canvas.
I had this same problem and none of the solutions here solved my problem. I had one opaque canvas with another transparent canvas above it. The opaque canvas was completely invisible but the background of the page body was visible. The drawings from the transparent canvas on top were visible while the opaque canvas below it was not.
fillStyle might not be what you are looking for because it can't really clear the canvas; it will either paint it with a solid color or with a transparent color which doesn't paint anything.
The trick that did for me relies on an implementation detail about the <canvas></canvas>. They "reset" when resized (tested on Chrome and Firefox):
canvas.width = canvas.width
This phenomenon initially struck me as a very annoying behavior, but it also became the only way I know to hard reset the canvas.
If you're exporting your canvas, remember to export as png!!
Been there, failed at that xD
Here's a minimal proof of concept of the default transparency of canvases, and using position: absolute to stack them on top of each other:
const canvases = [...Array(4)]
.map(() => document.createElement("canvas"));
canvases.forEach((canvas, i) => {
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
const saturation = 100 / canvases.length * (i + 1);
ctx.strokeStyle = `hsl(160, ${saturation}%, 60%)`;
ctx.lineWidth = 10;
ctx.strokeRect(i * 50 + 10, i * 15 + 10, 100, 80);
});
canvas {
position: absolute;
border: 1px solid black;
}
Can't comment the last answer but the fix is relatively easy. Just set the background color of your opaque canvas:
#canvas1 { background-color: black; } //opaque canvas
#canvas2 { ... } //transparent canvas
I'm not sure but it looks like that the background-color is inherited as transparent from the body.

Modifying the transparency of a gradient for a transparent arc on HTML5 Canvas

Here I have an arc with some transparency applied to one of the two gradients its using:`
ctx.arc(mouseX,mouseY,radius,0, 2*Math.PI,false);
var grd=ctx.createRadialGradient(mouseX,mouseY,0,mouseX,mouseY,brushSize);
grd.addColorStop(1,"transparent");
grd.addColorStop(0.1,"#1f0000");
ctx.fillStyle=grd;
ctx.fill();
Is there a way to now give the entire arc some transparency affecting only the arc and none of the rest of the canvas?
Thanks
Unlike SVG or HTML, there is no layering or grouping on an HTML Canvas. You can't wrap your arc/gradient in another lower-opacity element; you must propagate opacity (or tinting, or whatever) changes down to the end properties directly.
Your color #1f0000 is equivalent to rgb(31,0,0); use rgba to lower the opacity of this particular color stop.
var opacity = 0.55; //55% visible
grd.addColorStop(1,'transparent');
grd.addColorStop(0.1,'rgba(31,0,0,'+opacity+')');
You could make the color stop at the end an rgba color and give it transparency that way.