i want to set transparency for part of canvas
can I use globalAlpha like for all canvas except rectangle i create in the canvas ?
If you mean how to make a rectangle transparent after you have a bunch of things drawn to the canvas you can do the following:
/// clear a rectangle to make canvas transparent
ctx.globalCompositeOperation = 'destination-out';
/// set alpha using a fill color with transparency
ctx.fillStyle = 'rgba(0,0,0,0.5)';
/// fill rectangle which now will become partly transparent all the way
ctx.fillRect(40, 40, 320, 320);
/// reset composite mode
ctx.globalCompositeOperation = 'source-over';
Live demo here
If this is not what you mean then you need to plan your drawings. As mentioned elsewhere you can set globalAlpha before you draw something, draw it, then set globalAlpha back before you draw the next. Each draw after setting globalAlpha will be drawn with that alpha value (if the fill-style, stroke-style of image alpha uses transparency as well that will be a result of the two alpha values as they are multiplied).
globalCompositeOperation decides how it will be drawn, for example on top of existing content, instead of and so forth (see an overview here).
As I've said in the comments twice, you just have to set the global alpha to what you want, draw what you want with that alpha, then change the global alpha to a new value, then draw what you want in that alpha. That can be done as follows
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(255, 0, 0,1)';
ctx.fillRect(0, 0, 150, 50);
ctx.globalAlpha = 0.2;
ctx.fillRect(150,50,150,50);
Demo
Related
Say I have drawn a circle on a canvas that has something else drawn on it that stops me from clearing the canvas - due to the other element being randomly generated
var circleX = 50;
var circleY = 10;
var moveCircX = 2;
var moveCircY = 3;
function createCirc(){
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(circleX, circleY, 10, 0, Math.PI*2, true);
ctx.fill();
}
function circMove(){
circleY = (circleY + circMoveY)
//then validation to stop it from being drawn of the canvas
So what I'm trying to do is move the circle but clear the previous drawn circle from the canvas. So is there a solution to clearing the circle or would it be easier to create a sprite that replicates the circle?
Since your background isn't changing, the simplest strategy is to copy the background before you first draw your circle, then draw your circle. When you're moving, redraw that part of the background from the copy you kept, then draw your circle in the new place.
An efficient way to do that is to use getImageData and putImageData.
So, (my javascript is rusty, so this may not be perfect. Feel free to correct any mistakes), before the first time you createCirc, simply do:
imageData = ctx.getImageData(0,0, ctx.canvas.width, ctx.canvas.height)
And, in your circMove function, before you move and redraw the circle, you want:
ctx.putImageData(imageData, circleX, circleY, circleX, circleY, 2*circle_radius, 2*circle_radius)
(You don't define circle_radius, but I'm sure you must have a similar value. I'm using 2x the radius to presumably be the size of the image that is drawn.)
I want to use an image like this on canvas:
The user will "paint and fill" the image, but not on top of the outline.
The problem is:
If I put behind the canvas, the paint will cover the outline.
If I put over the canvas the image block canvas interaction.
Can you help me guys?
Use compositing mode "destination-over" to draw behind existing content (from image, vectors etc.). It's necessary that the existing content provide an alpha channel or composition won't work. If there is no alpha-channel you can convert inverse luma / matte (the white) to alpha channel.
// a quick-n-dirty demo
var ctx = c.getContext("2d");
ctx.lineWidth = 10;
ctx.moveTo(100, 0); ctx.lineTo(150, 150); ctx.stroke();
ctx.fillStyle = "#09f";
// KEY: composite mode -
ctx.globalCompositeOperation = "destination-over";
// draw behind the line
c.onmousemove = function(e) {
ctx.fillRect(e.clientX - 10, e.clientY - 10, 20, 20);
};
body {margin:0}
canvas {border:#777 solid 1px}
<canvas id="c"></canvas>
Here is the example of drawImage function. You can draw any preloaded image onto canvas. You can also try to place the <img> overlay in front of the canvas and disable mouse events for it using pointer-events: none CSS property.
I'm sure this question has been asked before I just can't find an answer to it yet.
I want to erase part of a black rectangle by drawing another, white rectangle on top, but a lot of the original black rectangle shows through as if it is being averaged:
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
context.globalAlpha = 1;
context.globalCompositeOperation = 'source-over';
context.strokeStyle = 'rgba(0,0,0,1)';
context.strokeRect(10,20,20,30);
context.strokeStyle = 'rgba(250,250,250,1)';
context.strokeRect(20,20,10,30);
js fiddle here What I want to see is a single black C on the left and an almost white rectangle next to it. Instead I see the single black C, a grey reverse C and the almost white line in between the two:
At first I thought it's because the box isn't black at all, instead it looks gray and with a little bit of alpha. So, after some googling I found this: Why isn't rectangle black in HTML 5 canvas?
basically, you draw you rectangle with a 1px wide border on a round pixel number, this means that the browser tries to draw on a half pixel. You should set the position to something .5 in order to avoid this problem:
http://jsfiddle.net/VdGa6/2/
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
// context.globalAlpha = 1; // this is the default so it's not needed
// context.globalCompositeOperation = 'source-over'; // this is the default so it's not needed
context.strokeStyle = 'rgba(0,0,0,1)';
context.strokeRect(10.5,20.5,20,30);
context.strokeStyle = 'rgba(250,250,250,1)';
context.strokeRect(20.5,20.5,10,30);
I'm trying to create a platform game in Canvas. I have main character and some enemies. When player touch enemy, he will lose some HP and he will be untouchable for about 3s. Now I have one problem. After loosing HP, I want to set opacity of character image to 0.5 (to show that untouchable thing).
var mainchar = new Image();
mainchar.src = 'mainch.png';
I don't want to use ctx.globalCompositeOperation = "lighter" or ctx.globalAlpha = 0.5 becouse both of them change the opacity of all elements (it's global). Is there any way to change the image opacity? For example 'mainchar.changeopacity' ?
You have to either change globalAlpha or draw the image to an off-screen canvas that has globalAlpha set, then draw this canvas onto the main canvas.
Just set alpha, draw the image and reset alpha back to full opacity. Setting alpha does not change the content that is already drawn to the canvas - it only applies to the next thing drawn (which would be the image in this case).
And of course, you can always prep your image with an alpha-channel in case of PNG images.
/// only image will have alpha affected:
context.globalAlpha = 0.5;
context.drawImage(image, x, y);
context.globalAlpha = 1.0;
You can also use save and restore.
context.save();
context.globalAlpha = 0.5;
....
context.restore(); //this will restore canvas state
I was wondering if there is a way to draw an image but give it a colourized effect.
If you consider games, when you want to place a sprite but theres an object in the way, often the object you try to place get a red tint to it to indicate it cannot be placed which is what im trying to achieve.
I currently draw it with an opacity here:
ctx.globalAlpha = 0.5
ctx.drawImage(image,abposx,abposy);
Is this possible to achieve without a library?
You can draw a semitransparent rectangle over top of it. For example:
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; // 1/2 opacity red
ctx.fillRect(0, 0, 30, 30); // Draw this over top of your image
Here's a demo.
For isometric images, all you have to do is create the appropriate path. Here's an example of that:
You can clip the overlay to your image by setting the globalCompositeOperation to source-atop:
ctx.globalCompositeOperation = 'source-atop';
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; // 1/2 opacity red
ctx.fillRect(0, 0, 30, 30); // Draw this over top of your image
ctx.globalCompositeOperation = 'source-over';
Here's a demo. You may also have to use a shadow canvas if the areas you're trying to draw on also have content, though.