This demo shows how it is possible to simulate a 3D scene in SVG, with the restriction that all the objects in the scene remain flat, and parallel to the projection plane (i.e. the screen). This is a setting similar to traditional cartoon animation where characters and scenery are painted on celuloid sheets ('cels'). The cels are then stacked together on a rostrum, to which proper lighting and additional effects are applied, and the final frame is shot on film.
Since the final setup is always a superimposition of 2D drawings, appropriately zoomed and positioned, it is possible to simulate it in SVG.
(I know the graphics could look better, but I'm not an artist. I prefer doing the maths. I used Amaya to edit the cels, by the way.)
Clicking and dragging the mouse will move the observer within the X-Y plane. If a key is pressed, clicking and dragging will make the observer move along X and Z, i.e. back and forth into the scenery. Rendering each frame is rather slow, so it might be desirable to turn off 'Higher Quality'. This simpler version should display faster:
Have a look at the source and read on, it's quite simple if you know a little bit of SVG and ECMAScript.
The cels are defined by one <g> element
containing an id attribute called "cels". The child
elements can be other <g> elements or any
primitive. Each child element should contain a depth
attribute from the http://people.w3.org/maxf/Parallax#cel
namespace, which indicates the position of that cel along the Z
axis. If depth is not specified, the depth is 0.
The ECMAScript script contains the position of the observer, the code to compute the final position and scale of each scale and the code to allow interactive motion. Interesting variables are
What the rest of the code does is let the user change the position of the observer through mouse movement and from the new position and then render the frame. Of course other means to change the position of the observer are possible, like a predefined path in 3D space for an non-interactive animation.
Dan Brickley gave me the idea of doing this when showing me a demo. Vincent Hardy and Dean Jackson provided help on SVG, especially about going around flaws in implementations.