Dom3D

Dom3D is a JavaScript cross browser (IE9+) engine for creating pseudo 3D (2.5D and some orthographic 3D) scenes out of DOM elements. It shares many characteristics with my 2.5D/3D engine for EaselJS: DepthJS, except it is for DOM elements rather than elements within EaselJS on the canvas. It has no dependencies, though it does play very well with MBTweener. It weighs about 21kb, and allows scenes to be set up via DOM elements (marking them as elements intended for 3D usage via certain classes) or by script through certain dom3d JS classes. It is not simply for 3D manipulation of elements; it is a fully forward kinematic engine with containers, sorting, etc. meant for creating 3D scenes. It utilizes cross browser capable affine-only transformations to mimic true 3D as best as possible while still keeping pixel perfect 2D layouts for any element without any 3D properties manipulated (i.e. if there’s no rotation and if the .z is at 0.

 

Download Dom3D Download Dom3D Examples Dom3D Docs

 


Inspect the page...the faces of that cube are div elements.


How It Works

Basically, this engine will give you the ability to manipulate certain DOM elements via .x, .y, and .z coordinate points and .rotX, .rotY, and .rotZ rotational values.

There are a few classes of 3D elements that can be created/utilized (they are namespaced with the prefix dom3d. unless you call a function dom3d.globalize() which will make them accessible anywhere via just the class names alone):

  • Element3D: represents DOM element intended to be manipulated as a plane in 3D.

  • PaperElement3D: represents a version of an Element3D which has a front and back that show depending on how the plane is facing.

  • Sprite3D: a version of Element3D that takes a spritesheet which represents a 360 degree view of something, and goes to the corresponding frame depending on the element’s rotation.

  • OrthoFace: a version of Element3D which renders completely orthographically within its container; neccessary since affine transformations need to be orthographic to properly line up in close quarters with each other, so this is used to construct primitives inside a Group3D

  • Group3D: represents a container for other Group3D objects, or for any of the above 3D elements.

  • Stage3D: represents the root of the 3D scene which contains any of the elements intended to render in that 3D scene.

Each instance of the above classes in the Dom3D library will end up representing one DOM element, which can be accessed via myDom3dObj.element, and each element represented by a Dom3D instance will have a property linking to it via element.dom3dObject. For details on each see the documentation.


Setting Up a Scene

Setting up a scene can be done via adding CSS classes to the DOM, or purely via script. Here’s an example of a few completely equivalent scene setups:

Via Script
<div id="my-stage3d"></div>

<script>
    var myStage = new dom3d.Stage3D('#my-stage3d');
    var myGroup = new dom3d.Group3D('<div></div>');
    var myElem1 = new dom3d.Element3D('<div></div>');
    var myElem2 = new dom3d.Element3D('<div></div>');
    
    myStage.addChild(myGroup);
    myGroup.addChild(myElem1);
    myGroup.addChild(myElem2);
</script>

We basically made our stage and told it what element in the DOM we wanted it to represent, then made a Group3D and 2 Element3D objects. Each of those we made create their own DOM element to represent them. We also could have used a selector to tell them to use a preexisting DOM element, like so:

<div id="my-stage3d"></div>

<div id="group"></div>
<div id="elem1"></div>
<div id="elem2"></div>

<script>
    var myStage = new dom3d.Stage3D('#my-stage3d');
    var myGroup = new dom3d.Group3D('#group');
    var myElem1 = new dom3d.Element3D('#elem1');
    var myElem2 = new dom3d.Element3D('#elem2');
    
    myStage.addChild(myGroup);
    myGroup.addChild(myElem1);
    myGroup.addChild(myElem2);
</script>
Via DOM
<div id="my-stage3d">
    <div>
        <div></div>
        <div></div>
    </div>
</div>

<script>
    var myStage = new dom3d.Stage3D('#my-stage3d'); // the rest is automatic
</script>

The instantiation of the Stage3D with an element that has children means it will automatically attempt to figure out a scene from those children. Any unmarked elements will be assumed to be intended as a Group3D if they have child elements, or a normal Element3D if they don’t. So this scene would end up with a Stage3D containing one Group3D which contains 2 Element3D objects. Basically the same as we set up in script above.

We can also manually tell it what we want each element to be via specific CSS classes that it will look for:

<div id="my-stage3d">
    <div class="dom3d-group3d">
        <div class="dom3d-element3d"></div>
        <div class="dom3d-element3d"></div>
    </div>
</div>

<script>
    var myStage = new dom3d.Stage3D('#my-stage3d'); // the rest is automatic
</script>

Of course, in the case of just Group3D’s and Element3D’s this doesn’t have much point (other than possibly being more readable), but it becomes very useful when wanting to set up a scene using other 3D types. The list of behaviors is as follows:

no dom3d- prefixed classes - Makes it a Group3D if it has children and an Element3D if it doesn’t.

dom3d-group3d - Will make this element a Group3D.

dom3d-element3d - Will make this element an Element3D. The object’s lockFacingFront property can be set to true by also including a CSS class dom3d-lockfacingfront. Any element inside one of these will be treated as a normal DOM element that is part of this plane being manipulated, not a 3D object with its own transforms.

dom3d-no-3d - Ignores the element and does not try to make it part of a 3D scene. This does not exclude it from you manually using it for an object you instantiate with script later.

dom3d-paperelement3d - Will make this element a PaperElement3D object. It can also have children elements that utilize the classes dom3d-front and dom3d-back to automatically make its front and back. Any element inside one of these will be treated as a normal DOM element that is part of this plane being manipulated, not a 3D object with its own transforms, including the front/back.

dom3d-sprite3d - Will make this element a Sprite3D object. When auto-making a Sprite3D in the DOM you must include 4 data-attributes: data-src="image-path.png", data-width="10", data-height="10", and data-frames="10" for the path to the spritesheet, the width of the frames, height of frames, and total frame count. They can also take the attributes data-regX and data-regY to set a registration point for the object. Should not contain any other DOM elements.

dom3d-orthoprimitive - Will make this element a Group3D and assume all it’s children should be made into OrthoFace objects.

dom3d-orthoface - Will make it an OrthoFace object. Any element inside one of these will be treated as a normal DOM element that is part of this plane being manipulated, not a 3D object with its own transforms.


To learn more download the examples and read the documentation.

Current version is 0.5.0 (released as Beta for now). Let me know about any bugs found.