Using multipe HTML5 canvas's to layer images - javascript

I started a web based game engine a while back, but used primarily jQuery to handle the sprites and animation, now I am learning the power of HTML5, by moving the game canvas to HTML5. So here's issue I am having: I'm using multple canvas as suggested from http://html5.litten.com/layers/canvaslayers.html to layer images.
This is not working for me, even if I set z-index to 999999: Here's my code->
http://snipt.org/xoKn
The objects layer is not on top of the tiles, thanks!

The code should work (at least the canvas handling part). I looked at your script and there may be the problem with loading images. You have
var tile = new Image();
tile.src = tiles[i]['bg'];
tilesCtx.drawImage(tile, tiles[i]['col']*32, tiles[i]['row']*32);
but it won't work since image is not loaded yet. Instead you should use
tile.onload = function(){
tilesCtx.drawImage(tile, tiles[i]['col']*32, tiles[i]['row']*32);
}
or something like that (i.e. you won't have a reference to the i variable so it needs to be modified).
Note that in the tutorial they use setInterval(drawAll, 20); which makes it work after a while (since after a time all images will be loaded).
Of course you may lose ordering of images (although this does not seem to be important), so preloading all images at the begining and then drawing them all at once is a good idea. Give it a try and let us now if it works!

If anyone is having a similar problem I managed to solve this by loading the first layer first then the lowest layer last. Apparently it seems that whatever is loaded first will be on top.
So my solution was to just move m objects loop above my tiles loop. Interesting to me, had no idea it mattered what loads first.

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

Disable/enable webGL Context in webGL/three.js

I have a cool project with three.js, and everything work as intended. It displays some mesh in different canvas, and there is my issue.
The project aimed to display many, many canvas, and each one have his own context, and it reach the deadly limit of 16 live webGL contexts. Since it's wanted to display more than that in a page, I'm searching to turn around this restriction, by disabling a context when it's not actually displayed on seen page. When the user will scroll, context will be disabled/enabled so I can put as many context as I want.
I've found this function : renderer.forceContextLoss() and with this one I can force the context disabling. But I didn't found anything to relaunch it. I manage to detect a loss of context, but not its restauration
If you got any idea of how I can achieve that, feel free to give me some tips.
Thanks in advance !
This has been covered elsewhere but the easiest way to make it appear like there are multiple canvases is to just use one instance of three.js, make it cover the entire window, put place holder divs where you want to draw things, and then use element.getClientBoundingRect to set the scissor and viewport for each scene you want to draw in each element
There's an example here.
Here's the answer in StackOverflow from which that sample originates
https://stackoverflow.com/a/30633132/128511
This will use far less memory than using multiple canvases, each of which would need it's own data, it's own shaders, etc...

Many images loading performance HTML/Javascript

Ok so after some searching and not finding the real anwser I was looking for I came with the following question in this situation:
I have a trading website that loads about 2300 PNG images of 37x50 twice, once in a left column and once in a right column. The images and all information that comes with it is inserted using jQuery on the document on the onLoad event. However loading 2300 images (even when the html came straight from the server) takes just TOO much time and even hangs new versions of chrome!. So now the quick solution was just to remove the images and show in a dynamic tooltip. Works great but got angry website users and it is indeed ugly.
So... I thought of some possible solutions but I have no idea what is good/bad practice here:
Make all images JPEG and reduce quality.
With the above or not: Add all images to 1 very large image, load it and draw 4600 canvasses based on locations in an array like 'imageArray["someimageID"] = { x = 0, y = 40 }'
Convert all images to base64, add them in an array 'imageArray["someimageID"] = "base64"' and draw 4600 canvasses.
And to an extend where I must think of as well that of all those 2300 images I have a small, medium and large version. (of which only the small ones, 37x40, are shown all together in a page)
Hope to get some nice insights on how to correctly solve such a problem!
Greets
If your images are static (not generated for every request) I think you should use CSS sprites. (similar to your own suggestion of lots of canvases).
Basically you create a div for each image you want to show (or some other container element) and set a background on it that takes a small portion of the big image that contains all images.
Example css:
img.icon1
{
width:50px;
height:50px;
background:url(spritesheet.png) 50 0;
}
in this example the 50 and 0 indicate the offset of your 50x50 icon in the spritesheet.
Update: Here http://css-tricks.com/css-sprites/ is an explanation that goes a bit further than my simple example.
First off, consider whether or not you actually need this many images, and loaded on the page all at once. Assuming you do...
Make all images JPEG and reduce quality.
Use the right format for what you're doing. JPEG is for photos. My guess is that since you have 37x50 pixel images that you're not showing photos. PNG is likely smaller from a file-size perspective in this case. It doesn't matter a whole lot though because the speed issue you're having is probably 80% browser time, 20% network time.
With the above or not: Add all images to 1 very large image, load it and draw 4600 canvasses based on locations in an array like 'imageArray["someimageID"] = { x = 0, y = 40 }'
Try it and see. I don't think this is going to help you. A canvas will have more overhead than a simple image.
Convert all images to base64, add them in an array 'imageArray["someimageID"] = "base64"' and draw 4600 canvasses.
Don't do this. You're adding 33% overhead to the file size, and again the load problem is mostly in your browser.
What you can do
Really question again whether or not you need this many images in the first place.
Cut down on network requests by using several hostnames to load the images. image1.example.com, image2.example.com, image3.example.com, etc. This will allow for more network requests in parallel.
Use your developer tools to verify where the problem actually is. Again, I suspect it's mostly client-side. Once you know the real problem, you can solve it directly.
I would advise if you can, creating a very low resolution sprite of images that can be placed to make it look like everything is loaded, then replace this with the proper images. Without better code/samples/what your images contain/ are they dynamic I am unable to give you a real answer with solution but at least it can lead you in the correct direction.
If your images are static, this will work fine, if dynamic there is not much else that can be done. I think some examples of the webpage you are creating would be great
The reason you're having problems is simply a massive amount of HTTP requests - something you should always be trying to minimize.
Like others are saying here, you're going to want to use a spritesheet technique if possible (it sounds like it is). A spritesheet will condense all of your images into one, removing 2299 of your HTTP requests.

HTML5 Canvas Ghosting Animation Issue?

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.

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.

Categories

Resources