Generally speaking, 2D and pseudo-3D (such as isometric and other axonometric projections) is much easier than 3D in many regards.
First of all, 3D game logic is way more complex than 2D - many simple techniques for things like collision detection and physics simply don't work in 3D, and even for those that do, wrapping your head around what happens is significantly harder in 3D. (After all, we humans are built for living on a relatively flat surface, so our brains are inherently 2.5D).
Another problem is that 3D artwork is a lot more complex. With 2D graphics, you only have one viewpoint to consider; if your sprite looks good in the editor, it will look good in the game. In 3D, you are typically using mesh models, and they are dynamically shaded, and both the viewpoint and the light direction can be virtually anything. Your models still need to look convincing at all times, which makes creating them much harder than 2D sprites.
And then there are the technical constraints of the web:
- WebGL is not yet universally available; getting it to run at all involves quite some black magic on some platforms, and even if it does work, performance characteristics are quite unreliable. 2D canvas, by contrast, works out-of-the box on any recent browser and OS. Doing 3D graphics on a 2D canvas, while perfectly possible, requires considerable trickery to get partial occlusion right (either clipping polygons against each other yourself, or using the sub-optimal Painter's Algorithm), and textured primitives are pretty much impossible. You'll also have to write all the lighting code yourself. A typical isometric graphics engine, however, is perfectly doable on a 2D canvas.
- Javascript is single-threaded, and wasn't meant to provide accurate low-granularity timing, which you need for smooth graphics. Hickups in animation smoothness are much more tolerable in a 2D game than in 3D, unless the 3D scene is mostly static and doesn't involve a moving camera.
Disclaimer: I haven't done this myself so all the information I am providing is only what I have found by researching
In theory, yes it is possible but not easy or practical.
Overview
So basically you are looking at having more-or-less a video encoder in-browser which can take the images you get form the canvas and convert it to video.
I had a few concerns first whether it was possible to actually do this, mainly:
- Is there a limit on Blob size? According to the W3C Blob spec, there doesn't seem to be.
- How the browser will handle the amount of memory required to do encoding?
In your circumstance, the animation duration is short enough that I do not believe that memory will be an issue (at least in terms of storing the images and video).
Let's get encoding!
I mentioned that you are basically having a video encoder. There are really two options for this, either build your own encoder or hope that someone has built some sort of encoder already.
An awesome answer on GameDev (and later found something similar on StackOverflow) explains that FFmpeg can create a video slideshow from images.
For those who don't know, FFmpeg is a free software project that produces libraries and programs for handling multimedia data
I know what you might be thinking, how is FFmpeg going to help me, that isn't JavaScript... right?
Well, before today I would have thought the same thing until I found videoconverter.js which apparently is a working copy of FFmpeg in JavaScript!
What's the catch?
Well, the FFmpeg JS file is kind of large weighing in at ~6MB gzipped (or ~24 MB uncompressed). The browser memory footprint is bound to be quite large!
I will note I am also making a few big assumption here:
- That the FFmpeg JS can actually read an image blob so we can build the video slideshow
- That FFmpeg JS actually supports all the same functions as the standard FFmpeg application
Besides FFmpeg, what is another way?
You can pick the format of video you want to output and write your own encoder!
To get you started, you could look at the spec for AVI (Audio Video Interlaced) or possibly Theora. You would be writing the information to a blob like you did in your text download example.
This stuff really is out of my skill set so I will leave the finer details of this up to you.
This isn't practical! This is a mountain of effort for a small video!
I said from the beginning that it wasn't going to be easy. What @ShivanDragon mentioned in the comments is the way I would personally go about it. Pass the images off to a server, get it generated and then downloaded.
There are some reasons why you might want it in-browser but I really don't see it being practical.
Edit: Hang on! I also asked whether sound is possible!
Whoops, I missed that part! Yes, adding sound is definitely possible though will add even more complexity into the mix. You can add audio as a second input file for FFmpeg which will insert it into the output video.
In terms of making your own video encoder, it will add a decent amount of extra effort for adding an audio stream. Probably best place to start is another few links to specs for audio like Vorbis or WAV.
Best Answer
Figured out what I was going for. Wanted to use loops to make the code as concise as possible, but ran into a few problems until I achieved this.
Now I can set
x
to repeat as many times as I want, in order to draw music staves in javascript, with the correct amount of adjustable whitespace in between them.Had to go back and look up some more information on loops, as suggested by tgkprog. Thanks!
Demo'able JS Fiddle at http://jsfiddle.net/ShawnCodes/K8j7u/1/