How multiple canvas elements affect performance? - javascript

I'm trying to make a simple game (view from above) on canvas. Please tell me, which is faster:
1) Draw everything on one <canvas> and calculate the areas that need to be redrawn.
2) Draw certain parts of the scene on different <canvas> elements and update each only if necessary. In the it variant, probably, I can also use a partial redraw.
For example, I could draw a map on one element, enemies on the second, and a cursor and etc on the third. When moving enemies, I could only redraw the second canvas.
Please explain in as much detail as possible which option is better and why. And could you please advise books that can deepen my knowledge on this issue? For beginners.

Most canvas games will use a sort of layering that you are describing. The furthest forward layer would be the HUD, either by a seperate canvas or HTML elements and this would only change if something happened to it, such as someone upgrading their player. Then after that it depends on how they draw the canvas. The simplest way would be to simply draw the portions of the map and obstacles are on the screen.

Use one canvas, trust me. If you have a sprite that does nothing but sit there it is still getting drawn 60 times a second so it makes no difference if it is moving or not changing or not if it exists on screen it is getting drawn regardless of change.

Related

HTML Canvas is slow due to big amount of tiles

I'm looking for a solution or enhancement on my working script.
Basically i want to draw a color for each pixels of a 800*800 canvas.
It works but it is a bit laggy, the JS array containing all the tiles may be part of the problem but i think it's more the "redraw" of the canvas every time we move it.
I created a simplified fiddle for you. Try to drag the canvas multiple time to see the slowing.
https://jsfiddle.net/cndapbaq/7/
function draw(translatePos){
I tried different approch and this is the one that is the most performant, but still not enough..
Thanks for the help..

Javascript/JQuery Calculation of Dimensions

I am looking to achieve something like this. A HTML view has a finite number of images (shown as red boxes in the image below). Are there any browser/jQuery APIs available today (cross-browser) which will let me calculate the dimensions of the remaining space (shown in green boxes) quickly? In the example shown below, it is easy to calculate the green area dimensions using simple geometry given the dimensions of the red boxes. But I am talking about very complex scenarios and complicated combination of images.
Appreciate any help. Thanks.
If you every images have absolute property, you can calculate dimension through top and left properties like $('#elementID').offset().top and $('#elementID').offset().left
From my experience working with DOM element dimensions, you cannot rely on them for exact values, and certainly can't really on them for the same values cross-browser. You can get OK results, but if you have complex scenarios then you will probably come undone at some point.
One way I have achieved similar things in the past is by drawing images to HTML5 Canvas. Using canvas you can have very fine-grained control. I have even iterated canvases pixel-by-pixel to get pixel perfect measurements of items on the canvas.
Check out this tutorial for a brief overview of drawing an image.
UPDATE
There is no easy way to do it. Using this method is low-level and will require you to use mathematics, and possibly byte-level image data from the canvas. However, if your problem is as complex as you suggest then you will have to get stuck in. When I did something similar I was also looking for an easy way to achieve what I wanted in the browser, then spent a month getting to grips with the canvas API, learning about byte-level colour data etc, but in then end I got what I needed, and ended up with something quite unique as it was difficult to achieve in a browser.
To get started, first I would say look at implementing a layered canvas by absolutely positioning multiple canvases on top of each other, then drawing a single image on each one. You already know the sizes of the images, and you can decide the coordinates of where to draw the image, so that's a start. In fact that may be all you need, you can track each image as you draw them by storing coords and dimensions, and you should be able to build up an accurate picture in numbers of where all your images are in 2D space.
Using those numbers you should then be able to calculate any empty spaces on there. However, that is a beyond me and probably a question for Mathematics Stack Exchange (which is actually down at the moment :D).

jQuery circular animation based on right and left controls and friction

This is a rather biggish question that i am just hoping to find some direction with.. I dont expect anyone to do this entire thing... But to rather learn how to go about projects like this. Here we go:
I am trying to achieve an this animation:
Basically whats happening here is, I need to have a semi oval shape and a ball constrained to it and when you press the left and right arrows it needs to slowly to quickly move left to right and based on the speed of the button clicks it needs to either complete the ramp or stop and drop. Imagine a skateboard and a ramp.
I know the basics of jQuery but the circular animation and friction effect is where i get lost..
Any Help/Direction/Advice Greatly Appreciated. Thank you.
I'm trying an answer for the animation part:
If you are ok with HTML5 then for the animations there are two ways to go:
Either use HTML5 Canvas, which really works well for providing dynamic content. Its basically a canvas on which you can freely draw. It's pixel based and has a good performance and, if done right it does not decline very much when drawing many elements). You should also double-buffer it in order to avoid any flickering when drawing.
Or use HTML5 Inline Svg. It's vector based, so resolution-independent and has good support for animating svg elements. In contrast to HTML5 Canvas the elements of the svg are DOM-Nodes, so you see the graphic elements directly in your DOM-Tree.
In order to sum up the trade-offs:
HTML5 Canvas
-Pixel-based
-Good Performance
-Free drawing
HTML5 Inline Svg
-Vector-based
-Animations built-in
-Elements are DOM-Nodes
For much more information, see
http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/

Canvas optimization when pixel changes are known

I am currently working on a web application where only single pixel changes are known, which are implemented like an event:
function pixelChanged(x, y, color)
These need to be drawn to a canvas. I have tried two methods to accomplish this:
draw pixels directly with fillRect
memorize pixels and put them on the canvas with putImageData every few microseconds
Now both of these methods seem to have a poor performance. The first one results in many redraws, the second one redraws the whole image, even if only a little area changed.
My specific question is, if there is a better method to implement this (maybe something like 1., but in some way delayed ?).
And if not, which method of these should I prefer ? How can I optimize it in this case ?
Thanks in advance and best regards,
copy
The approach I took is to break a large image into an NxN grid and redraw the specific areas that have changed. I found a decent size that balances the # of redraws vs the size of a redraw to be around 50x50px. If you need the exact optimal number for maximum px/sec drawn, I have it somewhere from benchmarks.
So if you have a 60x60 change, you'd be re-drawing between 4 and 9 50x50 squares.
Checkout this article with different approaches for canvas-optimization. I'd suggest you to combine several optimizations and see how it goes. Please note that our eye doesn't recognize frequent pixel changes on big area, so it make sense to buffer your pixel changes and draw several changes at once. Also please note that browser need several milliseconds to apply your changes, so don't make interval too small.

Redraw lots of objects on Canvas HTML

Is there a quick and efficient way to move lots of objects in canvas? Basically if there are around 1000 objects and I want to move all of them at once to emulate scrolling, it is very slow to redraw every single object by calling drawImage() 1000+ times.
Is there anyway to optimize this? I have an example link of the problem (and that's only with 100 objects): http://craftyjs.com/isometric/
Since canvas doesn't provide fast low level bitmap copying it's hard to do stuff in multiple layers and scroll for example the whole background at once and then only render the edges.
So what can you do? In short, nothing. Especially not when scrolling, sure you can do tricks with multiple canvases when you have a more or less static background but for moving objects there are hardly any performance improving tricks.
So, you've go to wait for Hardware Acceleration shipping in all majors browsers, I know this sounds ridiculous but I'm too waiting for that :/
The problem is that the canvas was never designed for game stuff. It was designed as, well, basically some kind of on the fly drawing thing, guess the designers had Photoshop clones in mind, but definitely not games, let alone the fact that there's no fast clear operation proves that, there's not even optimization in place when clearing the whole canvas with the same color.
If the images are already composited, not moving relative to one another, and defined by a rectangular region, then using canvas.drawImage() with a canvas as the first parameter and drawing to a sub-region should be significantly faster than re-drawing all the objects.
You could also just layer multiple canvases and slide the top canvas with the objects in HTML to scroll them.
Edit: Having really looked at your example, it seems to me that it should be implemented similar to Google Maps: create tiles of canvases and slide them left/right on the HTML page; once a canvas has been slid off the screen entirely (for example, off the left edge), move it to the other side (to the right edge) and re-use it for drawing. With this you will only need to re-draw whatever objects overlap the canvases that are moving on the edges.
You can draw all objects on a second, off-screen canvas and then only blit the whole canvas (drawImage() accepts canvas element).
However, if you're targeting desktop browsers, then this shouldn't be necessary. I've implemented tile engine (source) that simply redraws whole scene and naive implementation turned out to be pretty fast.
What I did to solve this problem was I had 10 squares on my screen and I wanted to animate them on a white background. So I drew a white rectangle over the canvas to clear the canvas so the animation would work. Does that make sense?
#Ivo By the way I read on http://www.w3.org/TR/html5/the-canvas-element.html that canvas was made for applications like games because it was a solution to get rid of the dependency on a external engine. Canvas is built in so it's kind of like a flash player built into your browser powered by JavaScript. I think it's fascinating.
You can use tiled rendering.
http://www.gamesfrommars.fr/demojsv2/ (better viewed with Chrome)

Categories

Resources