alex_h Posted November 27, 2013 Share Posted November 27, 2013 I'm thinking about a few places in my code where I could use canvas.toDataUrl to generate an Image object out of stuff I've drawn onto a canvas.I could then either add that image to the DOM, say if I use this technique to generate a background image for my game, or I could draw the generated image to my main 'stage' canvas to use in-game. The objective would be both to save on download size (in the case of game background) and also to cut down CPU overhead in the case of in-game content. It is this second usage that I'd like to get more information about. My understanding is that drawing complex shapes like text characters or elaborate patterns, or even groups of images with lots of transforms applied I suppose can be a processor intensive operation. So one way of cutting down this overhead is to only do the draw operation once, onto an offscreen canvas. You can then draw this canvas itself onto your stage canvas for each redraw, reducing it to a single draw operation rather than multiple ones. But then I've heard that drawing canvas to canvas is itself more expensive than drawing Image to canvas. And this is where it gets to stuff I'm less sure about. Is it true that drawing canvas to canvas is expensive? I don't know. But assuming that it is, could a possible way of alleviating this expense be to use canvas.toDataUrl as a means of generating an Image object from the offscreen canvas? Then you can just draw the Image to stage as normal on each redraw, only incurring a 'normal' expense for drawing an image, not an extra 'drawing a canvas' expense. I hope what I've written here makes sense, my descriptions sometimes tend to get a bit garbled! Anyway, can anybody advise whether what I'm talking about here sounds like a reasonable approach? I've looked into the question of support for canvas.toDataUrl, and I'm not interested in older versions of ie, I'm specifically targeting mobile devices so it should be alright on that front at least. What I'm really interested in is the question of whether there is likely to be a measurable performance benefit from generating an Image via toDataUrl from an offscreen canvas and using that in subsequent draw operations, as opposed to just using the canvas itself. If it comes down to it I suppose I can always create a benchmark test for this, but I thought it wouldn't hurt to see if anyone has any expert advise on the matter before doing so. Quote Link to comment Share on other sites More sharing options...
rich Posted November 27, 2013 Share Posted November 27, 2013 Pretty sure you'll find that these days there is next to no cost difference between drawing a canvas to a canvas and drawing an image. Quote Link to comment Share on other sites More sharing options...
alex_h Posted November 27, 2013 Author Share Posted November 27, 2013 Ok great, that's really helpful to know. Thanks! Quote Link to comment Share on other sites More sharing options...
YellowAfterlife Posted November 27, 2013 Share Posted November 27, 2013 There would be no reasonable difference between a 2D canvas and image, since canvases are raster in HTML5. As such, using toDataURL would logically be even a little bit slower, since image would have to be encoded and then decoded. Perhaps a single case where it would be appropriate would indeed be the use of background for element, but probably not as a separate DOM node, but rather a canvas element style property. That would have to be benchmarked carefully though. For small tiled backgrounds you can also make a "cache" image that would be slightly larger than canvas to permit covering the whole thing with a single draw-call. Most frameworks like Phaser or HaxePunk would already include such a thing, and for custom code you can implement it quite easily. Post is pretty old (and demo page got lost a while ago), but code is present and still works. Quote Link to comment Share on other sites More sharing options...
alex_h Posted November 28, 2013 Author Share Posted November 28, 2013 Hi, thanks for the advise, that's all very useful. probably not as a separate DOM node, but rather a canvas element style property. Could you clarify what you mean by a 'canvas element style property'? Do you just mean drawing the background to my main canvas? Quote Link to comment Share on other sites More sharing options...
YellowAfterlife Posted December 2, 2013 Share Posted December 2, 2013 Hi, thanks for the advise, that's all very useful. Could you clarify what you mean by a 'canvas element style property'? Do you just mean drawing the background to my main canvas?Late response, but I meant by applying the background as actual (CSS) style, node.style.backgroundImage = "url(" + canvas.toDataURL() + ")";If this proves fast enough (compared to canvas background drawing), you would only have to clear the canvas with transparent color, while background would be handled by browser. Quote Link to comment Share on other sites More sharing options...
alex_h Posted December 2, 2013 Author Share Posted December 2, 2013 Ah! I get you now, of course that does make sense. If I'm honest I went straight from Actionscript games development to working with HTML5 canvas, so I've really done very little with the DOM and CSS. It's one of those things I've been meaning to investigate further but just keeps getting pushed back by other more important stuff that bubbles up in front of it. Going back to the case in point, I've used DOM backgrounds behind my canvas before in other games, but didn't think of your suggested approach (due to reasons mentioned above) so ended up sticking the image as a DOM image in a separate div behind my game div. A lot of unnecessary faffing about I suppose, I probably could have just set it as the css background image of the game div itself. I will give that method a try, thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.