Purely speaking for the use of 2d.

First off, redrawing the canvas on every frame seems quite inefficient. Even when you can create multiple to not redraw everything etc. CSS animations to move objects work really well, why deviate?

What are the benefits of using the html canvas instead of just creating 'divs' in a 'body' to move and/or create objects on? What am I missing?

  • 3
    \$\begingroup\$ "Seems inefficient" is always less trustworthy than "I profiled this and measured the difference in efficiency". \$\endgroup\$
    – DMGregory
    Apr 7, 2022 at 11:05
  • 1
    \$\begingroup\$ Have a think about the amount of work, complexity and storage that may be required to save and restore parts of a scene, particularly a scene with many objects, particularly if those objects could overlap or intersect, particularly if parts of the background also scroll, move or animate. Yes, even in 2D. Then think about the simplicity of just clearing the scene and redrawing everything. \$\endgroup\$ Apr 7, 2022 at 11:43

1 Answer 1

  • The CanvasRenderingContext2D API is working in a way that is more familiar to game developers. Game developers who worked with other 2d graphics APIs before are used to having a function which says "draw this sprite on these pixel coordinates". Which the canvas2d API offers. Yes, I guess you could build a tilemap with ordered sprites on top using a couple hundred <img> elements positioned with CSS. But that can get pretty cumbersome. I don't know anyone who ever bothered doing that. People wanting to create 2d web games usually used Flash. And when Flash died, people switched to canvas (or to game engines using canvas).

  • CanvasRenderingContext2D can do things you just can't do with CSS. People who have more expertise than me at CSS 3 and all its official and unofficial features might be able to prove me wrong on specific examples, but fact is that CSS was not designed to do pixel-level graphics filtering and manipulation. Something you can do with canvas.

  • CanvasRenderingContext2D output can be cached and reused. A canvas does not need to be visible or even part of the DOM tree in order to draw on it. And a canvas can be used as an image source for the DrawImage function. That means that if you have elements in your game which require some time to create but then don't need any more changes, then you can just draw them once to an offscreen canvas and then draw that canvas (or parts of it) to the main canvas each frame. One use-case are character sprites using paper-dolling and palette swapping. When you have a 2d character with multiple equipment customization options which also use expensive recoloring algorithms, then you can just draw the whole spritesheet with all its equipment to an off-screen canvas. You can then use that off-screen canvas with the customized character as the spritesheet that appears on the on-screen canvas. So all that character customization doesn't eat more FPS than a regular sprite would.

  • Browsers usually have erase-and-redraw render loops anyway. What do you think will happen in the browsers rendering engine when you make visible changes to the DOM? HTML rendering engines aren't magic. The engine will also erase the whole render of the website and recreate it. Perhaps it can use techniques like dirty rectangles to avoid redrawing everything, but so can you when you use the canvas API. Sure, browser rendering engines often have countless hours of development and amazing optimization. But the use-case they are optimized for is rendering websites. Games usually don't behave in the way regular websites do.

  • Canvas and DOM can be used in combination. One argument for DOM you might hear is "Have you tried building an UI in canvas? It's either super annoying or requires a huge library which basically reinvents HTML+CSS". Well, you don't have to, because HTML and canvas can easily coexist within the same application. When I create a web-game, then I usually use canvas for rendering the game but create the UI using HTML+CSS and place it on top of the game canvas. I've also occasionally put another transparent canvas on top of the UI to draw things like particle effects which appear to come from HTML elements.

    Although it is possible to use canvases in a HTML dom tree, it is unfortunately not possible to do the reverse and render HTML directly to a canvas. Although there is a hack which allows to do that with certain restrictions by embedding HTML in an SVG object.

  • \$\begingroup\$ Ill need to look more into your first two points. Just read about dirty rectangles as well and also not too sure how that works. Thanks for the detailed points! \$\endgroup\$
    – rewfsdv
    Apr 7, 2022 at 13:38
  • \$\begingroup\$ I have created games using purely divs and CSS rendering. CSS transform uses the GPU and is very efficient. I found I could animate hundreds of divs without hickups. Also, you can use web components (custom components) to glue the code and visual objects together, which is very fun to do. But you are correct that most web games use canvas, which is in itself a reason to stick to the standard (otherwise you'll have to figure a lot of stuff out all by yourself). \$\endgroup\$
    – Kokodoko
    Jul 3, 2023 at 9:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .