I accomplished to fade a line with this code
function fadeOut(ctx, canvas) {
ctx.fillStyle = "rgba(255,255,255,0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
setTimeout(() => fadeOut(ctx, canvas), 50);
}
But the problem with this type of fading is, it fills the transparent background with a color and this cause the background div to fade as well.
The type of fading I would like to achieve is on gartic.io's background canvas.
You can check gartic.io
Related
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 am making annotations on images using a jpeg image and rectangles that I am drawing onto the image. I can then transfer the image to a canvas, and, using a for-loop, I can grab the bounds of the rectangular divs that I had drawn on the image to re-draw on the canvas.
The problem arises when I have multiple rectangles because the opacity decreases on each subsequent rectangle due to the fact that they are being layered, as such: `
function drawRectangleToCanvas(left, top, width, height, canvas, context, opacity) {
context.globalCompositeOperation='destination-over';
context.strokeStyle = 'rgba(0,255,130,0.7)';
context.fillStyle = 'rgba(0,0,255,'+opacity+')';
context.rect(left, top, width, height);
context.setLineDash([2,1]);
context.lineWidth = 2;
context.fill();
context.stroke();
}
From my understanding, the context.globalCompositeOperation='destination-over' causes the rectangles to be placed onto the image like slices of bread. With each rectangle that is drawn on the div, the opacities overlap, causing the opacity to increase by a factor of, in this case, 0.1. This is what the issue looks like: Canvas with layered rectangles and opacity problems.
How can I just add all the rectangles without this opacity issue? I call this method for each and every rectangle that I have, so I didn't know if I could put all the rectangles in an array or what. Any suggestions to fix this would be helpful.
EDIT: The darkest rectangle is the first one to be drawn, just to add some information.
Not completely sure what you want but you can leave out the calls to the stroke and fill methods until you have defined all the rectangles.
// Not much left to do in the function but just here to illustrate
// that creating the rectangles should be put together
function drawRectangleToCanvas(left, top, width, height, canvas, context){
context.rect(left, top, width, height);
}
context.globalCompositeOperation='destination-over';
context.strokeStyle = 'rgba(0,255,130,0.7)';
context.fillStyle = 'rgba(0,0,255,'+opacity+')';
context.setLineDash([2,1]);
context.lineWidth = 2;
context.beginPath();
while(??? ){
// loop and define all the rectangles
drawRectangleToCanvas(... //
}
// once all the rectangles are defined
// call the fill and stroke to render them
context.fill();
context.stroke();
This will stop them compounding the alpha values
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 building a website and I need a user to be able to select an image (a transparent gif with black sign on it) and select a color. I have all the gifs in black with transparent background.
How can I change the color of the gif (the black only) to the color the user chose? I was thinking about using a canvas for this but I'm not sure...
You can use a canvas for this. There is no need to iterate the pixel buffer as many suggests and I would recommend avoiding if possible for two reasons:
CORS restriction may apply if image is loaded from a different origin
Performance
There is a much easier way involving composite modes:
Live demo
/// load image here, then:
function render() {
/// this composite mode clears the canvas as well
ctx.globalCompositeOperation = 'copy';
ctx.drawImage(img, 0, 0);
/// this mode fills in whatever, in the image
ctx.globalCompositeOperation = 'source-in';
/// color to change GIF to:
ctx.fillStyle = '#00c';
/// fill color into non-alpha pixels
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
The copy mode works here as the image is the only thing we want to draw to the canvas. If you need to draw in other details as well then use source-over instead and manually clear the canvas using clearRect().
Tip: You can also draw another image on top instead of a fill color.
Original GIF
Changed to blue color
ctx.fillStyle = '#00c';
Changed to red color
ctx.fillStyle = '#c00';
etc.
Assuming that you want to change the color of the black parts of the image (not the transparent parts) you'll have to use canvas to get the black pixels of the image and draw a new image replacing these pixels with the color your user has chosen.
If you want to replace the transparent parts, simply setting a background color using CSS will do the trick.
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.