CSS ANIMATION wrote:
For a while I’ve been blogging about making all sorts of 3D-style effects using CSS. In this post I take it one step further and try to make the scenes look even more three dimensional.
This double-image technique is most notably used in the new Oculus Rift headset. While I don’t have one to test this against, I believe it’s possible to display HTML pages within the headset, so some form of this technique might be useful there.
Set the scene
To get started we’ll create a simple 3D scene using some HTML.
<div class="stage">
<figure class="cube">
<span class="back">S</span>
<span class="top"></span>
<span class="bottom"></span>
<span class="left">3D!</span>
<span class="right">S</span>
<span class="front">C</span>
</figure>
</div>
We have a containing stage div here that will act as a stage for the cube to sit on, and within it the cube figure itself. The cube is made up of 6 parts.
The “stage” div is needed so that the browser can establish some important 3D-related settings, such as the depth of the scene and the angle we’re looking into the scene at. These things we set with the CSS.
.stage {
width: 480px;
height: 500px;
margin: 10px auto;
position: relative;
perspective: 1600px;
}
This CSS sets up the stage with some proportions and sets a perspective value. Perspective describes the depth of the scene, with smaller values producting more extreme-looking results. In this case, 1600 pixels looks pretty good, but you can try different values in your own scene to see how it feels.
Building the cube
The cube itself is made up of six elements. Using the CSS3 transform property, we can manipulate these spans in the 3D space and position them where we like. First though we need to tell the browser that our intention is to move things around in 3D. Some CSS achieves this.
.cube {
transform-style: preserve-3d;
transform-origin: 100px 50%;
position: absolute;
top: 120px;
left: 140px;
}
The main parts to note here are the transform-style and transform-origin properties. These tell the browser that this and any child elements will be capable of transforming within the context of the “stage” figure, as well as describing the point around which any rotation, scaling or skewing can happen.
Next up we need to specify the dimensions of the cube faces, and then magic them into place using the transform property.
.cube span {
color: white;
display: block;
font-size: 100px;
height: 200px;
line-height: 200px;
opacity: 0.5;
position: absolute;
text-align: center;
width: 200px;
}
.back {
background-color: #f00;
transform: rotateY(180deg) translateZ(100px);
}
.top {
background-color: #ff7400;
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
background-color: #aaa;
box-shadow: 0 10px 100px rgba(0, 0, 0, 0.7);
transform: rotateX(-90deg) translateZ(100px);
}
.left {
background-color: #099;
transform: rotateY(-90deg) translateZ(100px);
}
.right {
background-color: #0c0;
transform: rotateY(90deg) translateZ(100px);
}
.front {
background-color: #ff0;
transform: translateZ(100px);
}
To make things more readable, I’ve removed the various “-webkit” and “-moz” prefixes from the tranform properties here.
This CSS describes the general rules for the spans, that they be 200 pixels wide for example, and have white text. The rules that follow rotate and position each of the various faces using rotate and translate. Each face is given a background colour also.
Making it stereoscopic
Now that we have a scene with a 3D object, we can double it up and make it stereoscopic. Start by doubling up the HTML into a left and right div.
<div class="container">
<div class="left">
<div class="stage">
<figure class="cube">
<span class="back">S</span>
<span class="top"></span>
<span class="bottom"></span>
<span class="left">3D!</span>
<span class="right">S</span>
<span class="front">C</span>
</figure>
</div>
</div>
<div class="right">
<div class="stage">
<figure class="cube">
<span class="back">S</span>
<span class="top"></span>
<span class="bottom"></span>
<span class="left">3D!</span>
<span class="right">S</span>
<span class="front">C</span>
</figure>
</div>
</div>
</div>
The intention here is to divide the screen up into two, and place one cube beside the other. We again use some of that magic we call CSS to achieve the goal.
.container {
margin: 0 auto;
width: 960px;
}
.left, .right {
height: 100%;
overflow: hidden;
width: 50%;
}
.left {
float: left;
}
.right {
float: right;
}
Our example doesn’t need to be full screen sized, so I’ve chosen to set it within a container column. Each of the two divs is set to 50% width and floated left and right respectively.
We now have two identical 3D objects. This isn’t going be enough, we’ll need to adjust for the different angles each eye needs. To do this we will override each stage perspective-origin property.
.left .stage {
perspective-origin: 63.5% -340px;
}
.right .stage {
perspective-origin: 36.5% -340px;
}
The left stage is given a perspective approximately two thirds along the X-axis, to mimic what your right eye would expect, and the right stage given a value of around one third. I’ve tweaked these by hand so they may need to be adjusted a little to work with your project.
The end result should be two almost identical 3D CSS scenes, with slightly different perspectives.
You can see the
animated stereoscopic version here.
Source:
cssanimation.rocks/stereoscopic/