A common way to do trails when animating in Canvas is to overlay your entire context with a semi-transparent color or gradient. Like this:
context.fillStyle = 'rgba(255, 255, 255, .05)';
context.fillRect(0, 0, canvas.width, canvas.height);
// ...draw your next frame
A lot of the examples available on how to create trails use this methodology (I didn't author any of these examples):
http://codepen.io/gbnikolov/pen/VLLgRW
http://www.html5gamedevs.com/topic/13621-best-way-to-create-fading-trails/
http://www.growingwiththeweb.com/2012/10/creating-trail-effect-with-canvas.html
However, all of these seem to leave a slightly faded out trail of the "trail", so that the trail never really goes away. I know there's alternative ways to create trails, but my main question is:
Why doesn't the trail fade completely? Why does adding additional multiple layers of a faded color constitute that color in full?
Thank you for helping out my confused brain.
You could try filling a rectangle a little while behind whatever is creating the trail every frame, just set the color to whatever the background color of your canvas is. This should cover up the trail after it's reached a certain length.
Related
I would like to have the fireworks from https://codepen.io/haidang/pen/WRGXJv overlaying the interactive table+button from https://codepen.io/kimaro/pen/BjqYeo.
I have tried using two canvases, where the canvas for the fireworks has
z-index=1
and the canvas for the table+button has
z-index=0
I tried changing the following in fireworks.js:
ctx.fillStyle = '#000'; //old
ctx.fillstyle = 'rgba(0,0,0,0)' //full transparent background
however the table+button canvas doesn't show for me. additionally, when changing the fillstyles for fillrect methods to be transparent, the background of the firework canvas changes colour randomly.
Additionally, if I call the firework js at the end of my html, then I can't click on the button of the canvas layer underneath.
Edit: As has been pointed out by Archer, the button would have to be on the top canvas layer. In this case, the background of the table+button layer would have to be transparent, whilst the layer underneath has the desired background colour.
Edit 2: A friend suggested I could merge the layers, to overcome the issue of the button being on the layer below.
I need to clear a rectangle Drawn on Image in Canvas with out damage existing image. I can draw small rectangle points and clear that out. But the problem is when I clear rectangle it remains as white small patch on image.
Can someone tell me how to clear a rectangle on image without damage the existing image.
I have used following methods to clear rectangles but didn't work.
1) context.fillStyle ="white";
2) context.clearRect(xCoordinate, yCoordinate, 10, 08);
Thanks in advance!
Canvas doesn't work that way. It's a single layer, its also transparent by default. So with that in mind, you might be able to achieve what you want by simply giving the canvas element a CSS background. That way anything you draw on top of that background can easily be removed and the background will show through.
#backed-canvas{
background-image: url(http://www.placebear.com/300/200);
}
JSFiddle example: https://jsfiddle.net/yLf5erut/
There is one thing you can do.
When create a rectangle on the canvas just get the image data like:
var imgData = context.getImageData(xCoordinate, yCoordinate, 10, 8);
and draw the rectangle.
When clearing out the rectangle just place then image data back like this:
context.putImageData(imgData, xCoordinate, yCoordinate);
I suggest using 2 canvas elements one over another.
So you can have the original image drawn on the bottom canvas with low zIndex, and the top one with highter zIndex can be used to draw / clear whatever needed. This is a common practice, and for more complecated animations you will end up with better performance.
I have problem with canvas createPattern. I have two boxes, both will move after pressing a keyarrow:
Example:
http://jsfiddle.net/wA73R/1/
The problem is that the box background filled by createPattern also is moving. How to avoid that? Is there any solution? The big box is only an example (drawImage is not the good solution for me, I need something that will repeat background image).
Thank you for help
The problem is that the box background filled by createPattern also is moving.
Actually your problem is that the background is not moving - it is static, while you are drawing your rectangle to different positions.
How to avoid that?
The pattern will always be drawn at the coordinate origin, whose actual position is defined by the current transformation. In future you will be able to transform the pattern itself with the setTransform method, but since that currently is not implemented anywhere you instead will have to change the global transformation matrix.
In your case it means, that instead of drawing your rectangle at x/y, you translate the whole context to x/y and draw your rectangle at 0/0 then:
ctx.fillStyle=pattern;
ctx.save();
ctx.translate(boxes[i].x - left , boxes[i].y);
ctx.fillRect(0, 0, boxes[i].width, boxes[i].height);
ctx.restore();
(updated demo)
I'm trying to accomplish an effect similar to what you might see on the cartoon Chowder (example link) , where shapes serve as masking layers for a texture underneath that stays static. I've begun playing around with this idea by creating a render loop that clears the canvas, saves it's state, then draws a rectangular clipping region, followed by drawing the background texture that occupies the entire width and height of the canvas.
Here's the draw function:
function draw()
{
context.clearRect(0,0, 640, 480);
context.save();
x += velocityX;
y += velocityY;
context.rect(x, y, 40, 40);
context.clip();
context.drawImage(image, 0,0, 640, 480);
context.restore();
}
Basically it just runs at 60 frames per second, updating the position of the rectangle and clipping a background image inside the clipping region. (I know the code isn't structured perfectly, but I was just experimenting to see if this effect was even possible on the canvas).
http://jsfiddle.net/JERje/86/
The problem I seem to be having is that the clipping area from the previous iteration of the loop hangs around creating the weird effect that you see in the fiddle above. I've tried reordering everything in the draw() step of the loop, but the only thing that seems to work is the canvas.width = canvas.width trick for clearing the screen. I'd like to avoid this method of clearing the screen, since it doesn't seem to work in IE, and it also destroys the canvas state. clearRect() should work to clear the screen. What am I doing wrong?
You're using the same HTML5 Canvas paperback I am aren't you.
If you set up an adhoc canvas as I did on your jsfiddle like so:
var newCanvas = document.createElement('canvas');
newCanvas.getContext("2d").drawImage(image,0,0);
A function such as this would be able to hack a section out of that canvas:
context.putImageData(newCanvas.getContext("2d").getImageData(x,y,40,40),x,y);
Thus giving you the chowder effect. Good show man, good luck. Pst me if it doesn't work
EDIT: However this solution will ignore some context scaling transformations. Just be smart about how you handle scale on your own (and you really should be anyways if you want the true "chowder" effect)
So, feel pretty dumb about this, but apparently when you call rect() you also have to make sure to call closePath afterwards in order to close the clipping area. Glad I figured it out finally, now on to adding multiple layers!
Here's the working fiddle: http://jsfiddle.net/JERje/129/
I wish to draw a rectangle on my canvas but stretching the start point. but how do i erase the previous rectangles drawn during the process. I mean if my background color is red and i want to draw a black rectangle over it. while erasing the intermediate rectangles drawn during rubber banding, i wish to retain the background.
The question is a little hard to understand, but I'm assuming what you want to do is the following using getImageData and putImageData:
// save the entire canvas (in this example, its 500 x 500) to be restored later
image = context.getImageData(0, 0, 500, 500);
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height); // clear entire canvas
context.putImageData(image, 0, 0); // restore entire canvas saved previously
/** Now, draw other stuff on top of the canvas **/
}
You need to redraw the portion of the background the black rectangle previously occupied. It may be simpler to just redraw the entire background.
You simply have to keep track of every single object you want to draw and redraw every single one of them each frame.
You can optimize the process a bit, but you must keep track of each thing drawn so you can redraw.