Dynamic 3D with CSS and the DOM
Published: 4th August 2006
The visual result was not too bad - the perspective is reasonably accurate, if a little too tall; but there's no depth or shading to the walls, so the sense of 3D is conveyed by the perspective lines alone. But the real problem was how laborious it was to program: each view is comprised of about a dozen vertical stripes, each of which contains an image, and for each point on the map and each direction of that point, I had to manually work out which images go together to make that particular view! Extremely tedious and time-consuming work, and so it was impractical to create very large dungeon areas to play in.
The game worked okay (in IE5!) and I was still proud of what I'd made, but pretty soon I'd forgotten about it, and moved onto pastures new.
But then one day...
Turn the clock forwards to 2006, and for no particular reason, I remembered all this. Pretty soon my mind had come round to wondering whether it could be re-done, without using images or vector formats, use Tantek's technique of creating shapes out of the interaction of CSS borders.
The principle is very simple (examples are images, not code):
- If an element has a very thick border (say, 50 pixels), and co-inciding borders are different colors (say, red on the left and blue on the top), then the intersection of those borders creates a diagonal line (fig1).
By varying the relative border-widths,
different angles can be created; and by using
"transparent"as one of the border colors, the diagonals can run against transparency (fig2).
- So finally, wrapping another element around the first, and then using CSS clip on the outer element so that only a corner of the inner element is exposed, we can effectively create a right-angled triangle of any size, with a choice of four orientations (depending on the outer clip), and with transparency on all three sides (fig3).
Once we can do that, it's simply a case of working out how many to make and where to position them, and then we can indeed create 3D perspective drawings using CSS alone! But of course that's still a lot of calculation - nobody wants to sit there working out the lines involved in all those different views - so in steps the DOM!
And all done without tedium! The viewer's input data is a 2D dungeon floor plan, and each 3D view is created on demand. This makes it quick and easy to create very large dungeon areas, and also means that details of the visual output - such as the shading and depth of perspective - can be edited and fine-tuned over time.
So where do we go from here?
Right now, the answer is
nowhere - I have too many other things to do!
But longer term there are neat possibilities to explore: a gaming framework for puzzles, challenges and combat among multiple players; an AJAX-powered online environment; perhaps an API so that users can design and host dungeons themselves. It should even be possible to build a text-transcoder, to make the game more accessible by dynamically creating a description of each view.
And of course, what's already there still needs some work! The shading algorithms aren't quite right, and there are rounding errors in the output, particularly evident towards the end of a long corridor.
But in the meantime, if you feel like developing this further, or if anything I've done here is useful to you - be my guest