Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full CSS 3D page - camera implementation

I want my page to be completely a 3D space, I don't know much about 3d but my Idea is to have the body be my view-port and the world is a div where my transformed content resides. I need a function that takes an orientation and position vector(or camera object?) as parameter and internally with CSS transformations it gets the world div transformed so the screen faces the desired part of the page. Example page, simple room.

<body>
    <div id="world">
        <section id="left-wall">...</section>
        <section id="right-wall">...</section>
        <section id="front-wall">...</section>
        <section id="floor">...</section>
    </div>
</body>

The script.

var cam = Camera(),
    world = document.getElementById("world");
cam.setPosition([x,y,z]);
cam.setOrientation([x,y,z]);
transform(world,cam); // world gets transformed

How would transform() function be? I'm not sure if it's the correct approach or if I should do it differently.

like image 693
olanod Avatar asked Mar 07 '13 23:03

olanod


1 Answers

Keith Clark's CSS3 first-person shooter seems to use a HTML structure like the following:

<div id="viewport">
    <div id="camera">
        <div id="assembly">
            <!-- Geometry elements inside here -->
        </div>
    </div>
</div>

In his demo the "camera" handles the rotation but the movement is handled by translating the "assembly", which is the container for the rest of the elements. An important part of this is to apply perspective to the viewport and preserve-3d to the camera so that a true 3D space is used inside it:

#viewport {
    -webkit-perspective: 700px;
}
#camera {
    -webkit-transform-style: preserve-3d;
}

Your geometry elements nested inside the assembly will have their 3D transforms interpreted relative to the assembly's position because of the preserve-3d style.

We can then implement your transform function something like this:

function transform(cameraElem, assemblyElem, camera) {
    var orient = camera.getOrientation();
    var pos = camera.getPosition();
    cameraElem.style.WebkitTransform = "rotateX(" + orient[0] + "deg) " + 
                                       "rotateY(" + orient[1] + "deg) " +
                                       "rotateZ(" + orient[2] + "deg)";
    assemblyElem.style.WebkitTransform = "translate3d(" + (-pos[0]) + "px, " +
                                                          (-pos[1]) + "px, " +
                                                          (-pos[2]) + "px)";
}

Of course all of the above only supports WebKit's flavor of 3D transforms but it should be a simple matter to extend this to support the Mozilla variant and the standard (non-prefixed) variant.

like image 72
Martin Atkins Avatar answered Sep 25 '22 02:09

Martin Atkins