HTML5 Canvas Ghosting Animation Issue? - javascript

I have been looking at plenty of tutorials on how to do proper HTML5 animations using javascript and request animation frame and even in the demos it seems like the animations look blury like the image being redrawn leaves a ghosted image of itself behind for a breif second. But then I see games like microsofts ported version of cut the rope that appears to have fixed this issue. Does anyone know a way to make this canvas effect less apparent?

I'm guessing the problem you have is that the new image is being redrawn before the previous image was cleared. I suggest making sure the canvas is cleared, or at least the area in which the image is being re-drawn. Although, I experimented with clearing the whole canvas vs clearing a specific section of the canvas, and up to a certain size (roughly 800x600), clearing the whole canvas was faster.
I use canvas for my (in-progress) game: http://www.dacheng.me/dBoom
Feel free to browse the JS source code!

I think what you're looking for is window buffering:
http://en.wikipedia.org/wiki/Multiple_buffering
Basically the idea is to use two different windows/canvas elements that are interchanged after being drawn completely so that you're switching between fully drawn "frames". This technique is used in OpenGL and almost any other legitimate graphics program that exists today.

Related

Using Canvas to display images for animation purposes

I'm getting into web animations, WebGL, Canvas, ThreeJS, GSAP and all those fun tools. I'm investigating different websites and how they're able to achieve certain effects.
I am mind blown by these two sites: https://14islands.com/ & https://www.hellomonday.com/.
Their animations look simple(ish). Liquid effect on images. I know with ThreeJS filters or WebGL or other Canvas libraries you can achieve the effects. What I don't understand is that both of these sites have a full-sized <canvas> element fixed to the background. And render almost all the images on the site through the <canvas> rather than pure HTML elements.
This allows to have all images to have really dope effects. But what I don't understand is how can they sync the positions and sizes of the images with HTML DOM elements so perfectly?
This seems like a nightmare to code. Also wouldn't it be a huge performance burden to update every image on the canvas when the user scrolls or resizes the page?
I believe I'm missing something. Perhaps there's a library that handles most of this?
If there are any simple examples, I'd love to see them.
Thank you for your time :)
Welp turns out this can be done quite simply with ThreeJS. Perhaps there are ways as well but this seems easiest to me.
TL;DR: You can create a scene for a div, and you can do this multiple times with ThreeJS so that it renders a scene within the specified div.
Demo: https://threejs.org/examples/?q=multiple#webgl_multiple_elements
Code: https://github.com/mrdoob/three.js/blob/master/examples/webgl_multiple_elements.html

How to cache static canvas areas in order to gain performance

I am using createjs library, and my game has a large bitmap on the background, in order to fill a window in full HD resolution. In lower resolutions i use a pan and scan like method. But the action is always limited in a smaller area of the canvas.
So i would like to know if it is possible, and how, to gain performance by caching static areas, or using any other technique.
For the sake of the argument here is a graph that demonstrates my situation :
I 've already tried to put the background image behind the canvas element using CSS here :
How to center a canvas on top of a background image
But CSS is driving me insane...so please bear with me...
:)
Thank you in advance!
In EaselJS every DisplayObject has a cache method, which is exactly doing what you want - it takes the painted stuff and puts in on a off-screen Canvas: http://www.createjs.com/docs/easeljs/classes/DisplayObject.html
Afterwards it takes the image-data from the off-canvas for every repaint (basically it's just a drawImage call afterwards).
Try to only cache painted areas - if you cache empty areas, you will lose performance. However if your background is just a static image you should still keep it as a normal DOM/CSS background - there isn't any performance benefit from caching a bitmap.
I had the same idea once, and I think what you are asking for is getImageData() and putImageDate()
image = context.getImageData(x,y,width,height);
context.putImageData(image,x,y);
However, I still found the performance of this to be very poor (sorry, I can't provide any actual numbers any more), and the best and also most popular way to achieve better performance seems to be to make a second canvas just for the background, or, if you really just have a static background image, use pure CSS like you originally wanted.
context.drawImage() can also draw from another canvas element, maybe you can utilise this in some way and create inivisible "canvas caches". But I still think that it's easier to learn CSS than implement something like this.
I am not familear with createjs, but you can try to draw / clear only on active area. This way you will not redraw inactive areas with each frame.
if inactive areas are not completely static, you can use separate canvas elements for them, and draw those on the main canvas once something have changed on that area (inactive area). I ho

Most efficient way to draw particles in HTML5 on iPad 2

I'm trying to create moving lights with trails for an HTML5 website/app targeted at iPad 2.
I wonder what the best way to do this is and whether using HTML5 is viable at all. I chose HTML5 because it's easier and cheaper to develop and deploy than native iOS apps with Objective C. Of course if it turns out that HTML5 simply doesn't offer enough performance I might have to swallow the bitter pill.
Anyway to give you an impression what I'm talking about, this is what I got so far:
screenshot http://devdali.no-ip.org/mathias/test-lights/screenshots/1.jpg
Or you can see it in action here (only works in webkit based browsers).
At first I tried using HTML5 canvas and drawing radial gradients as particles in similar manner you see above. It worked but the framerate was horrible even on my desktop computer!
So after a bit of reading I found out that CSS3 transforms may be hardware accelerated, so I build the version you see above. Every "particle" is a 64x64 png image. For each light there is the "head" light (one img) followed by a trail consisting of 115 img elements. Each img element is transformed using "translate3d" (as well as scale and rotation). Also the opacity of each element is adjusted dynamically.
Doing it this way provided much better framerates on my computer, but I doubt the iPad 2 will handle it.
I'd be grateful if anyone could give me some hints on how to improve the performance of this in general and considering the target platform.
Thanks for any help in advance!
If you accept small changes to the effect, some other procedure may work fast:
Instead of drawing the light's trails by the means of many particles, just draw the lights in their current positions in a Canvas element.
You can then darken the whole image at the beginning of a frame by filling a black rectangle with a very low opacity on top. This way the trails fade into dark, but would not alter their color like they do now.
The amount of drawing operations however will reduce vastly. The most costly operation would be filling the fading rectangle for every frame.
This should be built in the canvas. Check out EaselJS and this demo.
http://easeljs.com/
http://easeljs.com/demos/MusicVisualizer/index.html
You could optimize performances a LOT by using WebGL(, which is supported on the iPad2.)... which is not supported for basic html pages on ios safari as stated Nison Maƫl...
For the time being you only have canvas as a solution. Which will still give you better performances...
(You can check this blog for more info:
http://learningwebgl.com/blog/
With a little faith and time you'll be amazed!)

Html5 Flickering Javascript

I am working on a basic game in javascript. I don't use jQuery. The thing is that I have trouble in getting rid of the flickering. I noticed it happens because of the canvas clearing command. I read a lot of suggestions that recommended a sort of double buffering like having a buffer canvas on which I should draw which is not visible and another canvas which is visible and all the content is copied from the buffer. However, I doubt that even if I implement this I would still have the flickering as I still have to clear the visible canvas.
The final question is : What is the best way of getting rid of the flickering in my code? Thank you for your help.
this is a sample of my code:
http://edumax.org.ro/extra/new/Scratch.html
In your draw() method you call loadImages(), hence loading the images every time you redraw, ie every time the apple moves, hence the flickering.
Just put some breakpoints in your draw method it will all become pretty clear.
I guess what you want to do is to load the images at loading time then just draw... no need to load on every move.

How to use putImageData with animated gifs using HTML5 canvas and Javascript?

I want to manipulate the image data of every frame of an animated gif as it plays in the browser, and I want to do it using HTML5 canvas and Javascript. For example, I have an animated gif, and I want to convert every frame to grayscale as it plays in the browser. Is this possible? Whenever I manipulate the image data in an animated gif, only the first frame is shown (correctly manipulated) and the gif won't play any further. This would be a very useful technique if there was a solution for this. Thank you.
EDIT: Is there a way to query the current frame of an animated gif in Javascript, so I can just use putImageData into the image as the animation progresses?
As this page points out, you can use drawImage() to draw the GIF on the canvas, and at the moment it'll draw the current frame from the GIF in Gecko and WebKit -- but not in Opera, and also not according to the spec, so it's not a good idea to rely on this behavior. As far as I know there's no way to get individual frame data from the DOM; I looked into this for a while before writing jsgif (which was mentioned in another answer, but isn't really meant for any sort of practical use as it is -- it's very inefficient, for one).
If you can get away with unpacking the frames on the server and then animating them manually (e.g. like Gmail does), that might be your best option.

Categories

Resources