RotateX in CSS cube not working properly - html

I was learning to create a cube rotating effect. On hover if i replace the rotateX by rotateY the cube is rotating around Y axis centered. But when rotateX is present, the cube is not rotating about X axis centered. How do i implement proper rotation of cube?
#container {
perspective: 1000px;
perspective-origin: 0 0;
}
#cube {
position: relative;
top: 100px;
left: 100px;
width: 200px;
transform-style: preserve-3d;
transition: transform 2s;
transform-origin: 50% 50%;
}
#cube div {
position: absolute;
width: 200px;
height: 200px;
}
#front {
transform: rotateY( 0deg ) translateZ( 100px );
background-color: rgba(0,34,62,0.3);
}
#right {
transform: rotateY( 90deg ) translateZ( 100px );
background-color: rgba(110,34,162,0.3);
}
#back {
transform: rotateY( 180deg ) translateZ( 100px );
background-color: rgba(20,4,62,0.3);
}
#left {
transform: rotateY( -90deg ) translateZ( 100px );
background-color: rgba(80,134,2,0.3);
}
#top {
transform: rotateX(90deg) translateZ(100px);
}
#bottom {
transform: rotateX(-90deg) translateZ(100px);
}
#cube:hover {
transform: rotateX(360deg);
}
<html>
<body>
<div id="container">
<div id="cube">
<div id="front">
<h1>1</h1>
</div>
<div id="right">
<h1>2</h1>
</div>
<div id="back">
<h1>3</h1>
</div>
<div id="left">
<h1>4</h1>
</div>
<div id="top">
<h1>5</h1>
</div>
<div id="bottom">
<h1>6</h1>
</div>
</div>
</div>
</body>
</html>

If I understand you correctly, you just set the #cube's height to 200px
#container {
perspective: 1000px;
perspective-origin: 0 0;
}
#cube {
position: relative;
top: 100px;
left: 100px;
width: 200px;
height:200px;
transform-style: preserve-3d;
transition: transform 2s;
transform-origin: 50% 50%;
}
#cube div {
position: absolute;
width: 200px;
height: 200px;
}
#front {
transform: rotateY( 0deg ) translateZ( 100px );
background-color: rgba(0,34,62,0.3);
}
#right {
transform: rotateY( 90deg ) translateZ( 100px );
background-color: rgba(110,34,162,0.3);
}
#back {
transform: rotateY( 180deg ) translateZ( 100px );
background-color: rgba(20,4,62,0.3);
}
#left {
transform: rotateY( -90deg ) translateZ( 100px );
background-color: rgba(80,134,2,0.3);
}
#top {
transform: rotateX(90deg) translateZ(100px);
}
#bottom {
transform: rotateX(-90deg) translateZ(100px);
}
#cube:hover {
transform: rotateX(360deg);
}
<html>
<body>
<div id="container">
<div id="cube">
<div id="front">
<h1>1</h1>
</div>
<div id="right">
<h1>2</h1>
</div>
<div id="back">
<h1>3</h1>
</div>
<div id="left">
<h1>4</h1>
</div>
<div id="top">
<h1>5</h1>
</div>
<div id="bottom">
<h1>6</h1>
</div>
</div>
</div>
</body>
</html>

You need to set the transform origin according to the div size (one side of the cude). So I just changed the transform-origin: 100px 100px; for the cube like this:
#container {
perspective: 1000px;
perspective-origin: 0 0;
height: 500px;
}
#cube {
position: relative;
top: 100px;
left: 100px;
width: 200px;
transform-style: preserve-3d;
transition: transform 2s;
transform-origin: 100px 100px;
}
#cube div {
position: absolute;
width: 200px;
height: 200px;
}
#front {
transform: rotateY( 0deg ) translateZ( 100px );
background-color: rgba(0,34,62,0.3);
}
#right {
transform: rotateY( 90deg ) translateZ( 100px );
background-color: rgba(110,34,162,0.3);
}
#back {
transform: rotateY( 180deg ) translateZ( 100px );
background-color: rgba(20,4,62,0.3);
}
#left {
transform: rotateY( -90deg ) translateZ( 100px );
background-color: rgba(80,134,2,0.3);
}
#top {
transform: rotateX(90deg) translateZ(100px);
}
#bottom {
transform: rotateX(-90deg) translateZ(100px);
}
#cube:hover {
transform: rotateX(360deg);
}
<html>
<body>
<div id="container">
<div id="cube">
<div id="front">
<h1>1</h1>
</div>
<div id="right">
<h1>2</h1>
</div>
<div id="back">
<h1>3</h1>
</div>
<div id="left">
<h1>4</h1>
</div>
<div id="top">
<h1>5</h1>
</div>
<div id="bottom">
<h1>6</h1>
</div>
</div>
</div>
</body>
</html>
It did not work with percentage since the cube is not "straight" sided and the container uses perspective.

Related

Cube spinning on its corner

I have a 3D cube made from pure HTML-cum-CSS which is supposed to spin on one of its corners without the corner moving around the screen. Unfortunately, it doesn't quite do so, it rather wobbles along a line (2D) or around a circle (3D). What am I doing wrong?
#cube {
position: relative;
margin: 100px auto;
height: 100px;
width: 100px;
animation: 4s rotateforever infinite linear;
transform-style: preserve-3d;
}
.face {
position: absolute;
height: 78px;
width: 78px;
padding: 10px;
border: black 2px solid;
}
.one {
transform: rotateX(-45deg) rotateY(45deg) translateZ(50px);
}
.two {
transform: rotateX(-45deg) rotateY(135deg) translateZ(50px);
}
.three {
transform: rotateX(-45deg) rotateY(225deg) translateZ(50px);
}
.four {
transform: rotateX(-45deg) rotateY(315deg) translateZ(50px);
}
.five {
transform: rotateX(45deg) rotateZ(-45deg) translateZ(50px);
}
.six {
transform: rotateX(45deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
}
#keyframes rotateforever {
to {
transform: rotateY(360deg);
}
}
<body>
<div id="cube">
<div class="face one">one</div>
<div class="face two">two</div>
<div class="face three">three</div>
<div class="face four">four</div>
<div class="face five">five</div>
<div class="face six">six</div>
</div>
</body>
JSFiddle
Found the answer:
According to a post on Blender the left and right angle between the horizontal and the cube in its original position is not 45deg (as I assumed), but only 35.2644deg.
Therefore in my CSS, I had to change the values of each occurrence of a transform: rotateX(...) to 35.2644deg where I used to have 45deg and to 54.7356deg (90 - 35.2644) where I used to have -45deg.
Like so:
.one {
transform: rotateX(-54.7356deg) rotateY(45deg) translateZ(50px);
}
.two {
transform: rotateX(-54.7356deg) rotateY(135deg) translateZ(50px);
}
.three {
transform: rotateX(-54.7356deg) rotateY(225deg) translateZ(50px);
}
.four {
transform: rotateX(-54.7356deg) rotateY(315deg) translateZ(50px);
}
.five {
transform: rotateX(35.2644deg) rotateZ(-45deg) translateZ(50px);
}
.six {
transform: rotateX(35.2644deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
}
I updated the JSFiddle.

Simple 3-D carousel in vertical direction not working properly?

I was making a carousel in the vertical direction, but on rotating 180deg of the X-axis, the backside of the carousel seems like its orientation is not proper in the 3D space.
I would prefer that the solution provided contains not just the code, but also reasoning why this is happening.
#container1 {
position: relative;
left: 100px;
width: 200px;
height: 600px;
transform-style: preserve-3d;
transform-origin: 0 300px 0;
perspective-origin: 100px 300px 0;
perspective: 800px;
animation-name: rotate;
animation-duration: 5s;
}
#keyframes rotate {
from {transform: rotateX(0deg);}
to {transform: rotateX(180deg);}
}
#container1 div {
position: absolute;
top: 225px;
width: 150px;
height: 150px;
}
#div1 {
transform: rotateX(0deg) translateZ(130px);
background-color: red;
}
#div2 {
transform: rotateX(60deg) translateZ(130px);
background-color: blue;
}
#div3 {
transform: rotateX(120deg) translateZ(130px);
background-color: green;
}
#div4 {
transform: rotateX(180deg) translateZ(130px);
background-color: brown;
}
#div5 {
transform: rotateX(240deg) translateZ(130px);
background-color: orange;
}
#div6 {
transform: rotateX(300deg) translateZ(130px);
background-color: pink;
}
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div id="container1">
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<div id="div5"></div>
<div id="div6"></div>
</div>
<script src="script.js"></script>
</body>
</html>
The problem is you put perspective in the #container. You should put the perspective in the "stage". Here you can the implementation: JSFiddle

Turn a CSS 3d Flip into a slideshow

I have a simple card flip animation from this example: https://desandro.github.io/3dtransforms/docs/card-flip.html
I would like to turn this (or something similar to this) into a slideshow mechanic, where I don't just flip front and back, but multiple elements, together with a back and forth button.
How would this be possible without asynchronous loading the next or previous element?
http://codepen.io/anon/pen/qbvvyp
See the example HTML element:
<section class="container">
<div id="card">
<figure class="front">1</figure>
<figure class="back">2</figure>
<!--
How To Make this a Slideshow?
<figure class="back">3</figure>
<figure class="back">4</figure>
-->
</div>
</section>
I did it by using 3 separate CSS classes:
turnedLeft (turned left, -180 degrees on the Y axis)
turnedRight (turned right, 180 degrees on the Y axis)
active (facing the user, 0 degrees on the Y axis)
and 2 functions:
prevSlide: adds turnedRight to the active slide, and makes the previous element active.
nextSlide: adds turnedLeft to the active slide, and makes the next element active.
This is dynamic, and will work for any number of elements inside the "card" div!
https://jsfiddle.net/gmsitter/vuob9bnx/
HTML:
<section class="container">
<div id="card">
<figure class="active">1</figure>
<figure>2</figure>
<figure>3</figure>
<figure>4</figure>
<figure>5</figure>
</div>
</section>
<button id="previous">Previous</button>
<button id="next">Next</button>
CSS:
figure {
margin: 0px;
font-family: sans-serif;
}
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
border: 1px solid #CCC;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
}
#card {
width: 100%;
height: 100%;
position: absolute;
}
#card figure {
display: block;
height: 100%;
width: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 140px;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
background: blue;
-webkit-transform: rotateY( 180deg );
-moz-transform: rotateY( 180deg );
-o-transform: rotateY( 180deg );
transform: rotateY( 180deg );
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
}
#card .turnedLeft {
-webkit-transform: rotateY( -180deg );
-moz-transform: rotateY( -180deg );
-o-transform: rotateY( -180deg );
transform: rotateY( -180deg );
}
#card .turnedRight {
-webkit-transform: rotateY( 180deg );
-moz-transform: rotateY( 180deg );
-o-transform: rotateY( 180deg );
transform: rotateY( 180deg );
}
#card .active {
-webkit-transform: rotateY( 0deg );
-moz-transform: rotateY( 0deg );
-o-transform: rotateY( 0deg );
transform: rotateY( 0deg );
}
JS:
var init = function() {
var r = 1;
var slides = $("#card").children();
$('#next').click(function(){
nextSlide();
});
$('#previous').click(function(){
prevSlide();
});
function nextSlide(){
if(r<slides.length){
var activeSlide = $(".active");
activeSlide.addClass("turnedLeft");
activeSlide.removeClass("active");
activeSlide.next().addClass("active");
r++
}
}
function prevSlide(){
if(r>1){
var activeSlide = $(".active");
activeSlide.addClass("turnedRight");
activeSlide.removeClass("active");
activeSlide.prev().addClass("active");
r--
}
}
};
window.addEventListener('DOMContentLoaded', init, false);

How to create a sphere in css?

I have trying to create a 3D sphere using just pure css, but I've been unable to generate the shape required. I've seen a cylinder but I can't find any reference to creating an actual sphere.
My current code looks like:
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.sphere {
height: 200px;
width: 200px;
border-radius: 50%;
text-align: center;
vertical-align: middle;
font-size: 500%;
position: relative;
box-shadow: inset -10px -10px 100px #000, 10px 10px 20px black, inset 0px 0px 10px black;
display: inline-block;
margin: 5%;
}
.sphere::after {
background-color: rgba(255, 255, 255, 0.3);
content: '';
height: 45%;
width: 12%;
position: absolute;
top: 4%;
left: 15%;
border-radius: 50%;
transform: rotate(40deg);
}
<div class="sphere red"></div>
<div class="sphere green"></div>
<div class="sphere blue"></div>
<div class="sphere yellow"></div>
<div class="sphere"></div>
however,
A: these are just 2D circles, not 3D shapes
B: I can't rotate these in 3d (I want to have a spinning image) similar to that of a globe.
Sorry if i missed anything, but I'm not too sure where I should go to ask this.
You might want to use 3D rotated circles:
This uses rotated circles to look like a spherical grid. the lesser no. of elements, the better performance.
Some elements have been rotated in X axis, and others in Y axis. I have filled different colours to show this:
#cont {
perspective: 10000px;
transform-style: preserve-3d;
-webkit-animation: rotat 1s linear infinite;
animation: rotat 10s linear infinite;
transform-origin: 50% 50% 50%;
}
.circ {
height: 200px;
width: 200px;
border: 2px solid black;
border-radius: 50%;
position: absolute;
top: 50px;
left: 50%;
margin-left: -100px;
transform-origin: 50%;
transform-style: preserve-3d;
background: orange;
}
.circ:nth-child(1) {
transform: rotateX(0deg);
}
.circ:nth-child(2) {
transform: rotateX(30deg);
}
.circ:nth-child(3) {
transform: rotateX(60deg);
}
.circ:nth-child(4) {
transform: rotateX(90deg);
}
.circ:nth-child(5) {
transform: rotateX(120deg);
}
.circ:nth-child(6) {
transform: rotateX(150deg);
}
.circ:nth-child(7) {
transform: rotateX(180deg);
}
/*other side rotated*/
.circ:nth-child(8) {
transform: rotateY(30deg);
}
.circ:nth-child(9) {
transform: rotateY(60deg);
}
.circ:nth-child(10) {
transform: rotateY(90deg);
}
.circ:nth-child(11) {
transform: rotateY(120deg);
}
.circ:nth-child(12) {
transform: rotateY(150deg);
}
.circ:nth-child(13) {
transform: rotateY(180deg);
}
.oth {
background: crimson;
}
#-webkit-keyframes rotat {
0% {
-webkit-transform: rotateY(0deg) translateX(0);
}
100% {
-webkit-transform: rotateY(360deg);
}
}
#keyframes rotat {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
<div id="cont">
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<!--rotated other side-->
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
</div>
You can also rotate some elements in Z direction, but that will make it even more buggy. Now if you fill the same colours in circles, it almost looks like a sphere:
#cont {
perspective: 10000px;
transform-style: preserve-3d;
-webkit-animation: rotat 1s linear infinite;
animation: rotat 10s linear infinite;
transform-origin: 50% 50% 50%;
}
.circ {
height: 200px;
width: 200px;
border: 2px solid black;
border-radius: 50%;
position: absolute;
top: 50px;
left: 50%;
margin-left: -100px;
transform-origin: 50%;
transform-style: preserve-3d;
background: crimson;
}
.circ:nth-child(1) {
transform: rotateX(0deg);
}
.circ:nth-child(2) {
transform: rotateX(30deg);
}
.circ:nth-child(3) {
transform: rotateX(60deg);
}
.circ:nth-child(4) {
transform: rotateX(90deg);
}
.circ:nth-child(5) {
transform: rotateX(120deg);
}
.circ:nth-child(6) {
transform: rotateX(150deg);
}
.circ:nth-child(7) {
transform: rotateX(180deg);
}
/*other side rotated*/
.circ:nth-child(8) {
transform: rotateY(30deg);
}
.circ:nth-child(9) {
transform: rotateY(60deg);
}
.circ:nth-child(10) {
transform: rotateY(90deg);
}
.circ:nth-child(11) {
transform: rotateY(120deg);
}
.circ:nth-child(12) {
transform: rotateY(150deg);
}
.circ:nth-child(13) {
transform: rotateY(180deg);
}
.o {
border: none;
}
#-webkit-keyframes rotat {
0% {
-webkit-transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(360deg);
}
}
#keyframes rotat {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
<div id="cont">
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<!--rotated other side-->
<div class="circ o"></div>
<div class="circ o"></div>
<div class="circ o"></div>
<div class="circ o"></div>
<div class="circ o"></div>
<div class="circ o"></div>
</div>
The below answer is not an actual 3D shape. It only gives a slight illusion of being 3D, however, depending on your use case, you may be able to 'fake' it:
html,body{margin:0;padding:0;background:#222;}
div{
height:300px;
width:300px;
background:url(http://lorempixel.com/300/300);
border-radius:50%;
animation:spin 3s linear infinite;
transform:rotate(-15deg);
position:relative;
}
div:before{
content:"";
position:absolute;
bottom:-50px;
border-radius:50%;
left:0;
height:10%;
width:100%;
transform:rotate(15deg);
background:rgba(0,0,0,0.6);
box-shadow: 0 0 10px 2px rgba(0,0,0,0.6);
}
div:after{
content:"";
position:absolute;z-index:12;
top:0;left:0;height:100%;width:100%;border-radius:50%;
box-shadow:inset -20px -20px 20px 2px #222, inset 20px 20px 20px 5px rgba(200,200,200,0.4);
}
#keyframes spin{
to{background-position:-300px 0;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
It's animating the background-position of the div, and by using box shadows, you could 'mimic' the shadowing of a 3D shape.
I use JavaScript to build the sphere which formed by many div elements. To maintain the browser performance, the div elements are made as little as possible.
var DIAMETER = 200;
var CELLS_PER_CIRCLE = 26;
var IMG_CELL = 'https://sites.google.com/site/zulnasibu/sphere/earth.png';
var NAME = 'sphere';
var WRAP = NAME + '-wrapper';
var _cssRules = '';
var _cellW;
var _cellAmount = 0;
var _imgW;
var _imgH;
function createFace(w, h, rx, ry, tz, ts, tsx, tsy, cname) {
var face = document.createElement("div");
var css;
var cssText =
'width: ' + w.toFixed(2) + 'px;' +
'height: ' + h.toFixed(2) + 'px;' +
'margin-left: ' + (-w / 2).toFixed(2) + 'px;' +
'margin-top: ' + (-h / 2).toFixed(2) + 'px;' +
'background: url("' + ts + '") ' + tsx.toFixed(2) + 'px ' + tsy.toFixed(2) + 'px;';
css = 'transform: rotateY(' + ry.toFixed(2) + 'rad) rotateX(' + rx.toFixed(2) + 'rad) translateZ(' + tz.toFixed(2) + 'px);';
cssText += addVendorPrefix(css);
face.className = cname;
face.style.cssText = cssText;
return face;
}
function createModel() {
var wrap = document.createElement("div");
var model = document.createElement("div");
wrap.className = WRAP;
model.className = NAME;
if (CELLS_PER_CIRCLE % 2 != 0) CELLS_PER_CIRCLE++;
if (CELLS_PER_CIRCLE < 4) CELLS_PER_CIRCLE = 4;
var baseAngle = Math.PI / CELLS_PER_CIRCLE;
var cellAngle = 2 * baseAngle;
_cellW = DIAMETER * Math.tan(baseAngle);
_imgW = _cellW * CELLS_PER_CIRCLE;
_imgH = CELLS_PER_CIRCLE / 2;
if (CELLS_PER_CIRCLE % 4 == 0) _imgH++;
_imgH *= _cellW;
var xc = Math.ceil(CELLS_PER_CIRCLE / -4);
var yc, rx, ry, tx, ty = -_imgH, tw, cang, cdia, cw;
for (var x = xc; x <= -xc; x++) {
rx = x * cellAngle;
cw = _cellW;
yc = CELLS_PER_CIRCLE;
if (Math.abs(rx) == Math.PI / 2)
yc = 1;
else if (Math.abs(x) != 1) {
cang = rx - Math.sign(x) * cellAngle / 2;
cdia = DIAMETER * Math.cos(cang);
cw = cdia * Math.tan(baseAngle);
}
_cellAmount += yc;
tw = cw * yc;
tx = (tw - _imgW) / 2;
ty += _cellW;
for (var y = 0; y < yc; y++) {
ry = y * cellAngle;
model.appendChild(createFace(cw + 1, _cellW + 1, rx, ry, DIAMETER / 2, IMG_CELL, tx, ty, 'cell' + x.toString() + y.toString()));
tx -= cw;
}
}
wrap.appendChild(model);
var style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet)
style.styleSheet.cssText = _cssRules;
else
style.innerHTML = _cssRules;
document.head.appendChild(style);
return wrap;
}
function addVendorPrefix(property) {
return '-webkit-' + property +
'-moz-' + property +
'-o-' + property +
property;
}
function showGeometry(elm) {
if (elm.checked)
document.querySelector('.sphere').classList.add('show-geometry');
else
document.querySelector('.sphere').classList.remove('show-geometry');
}
document.body.appendChild(createModel());
.sphere-wrapper {
position: absolute;
top: 50%;
left: 50%;
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
-o-perspective: 1000px;
perspective: 1000px;
}
.sphere {
position: absolute;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: center center -100px;
-moz-transform-origin: center center -100px;
-o-transform-origin: center center -100px;
transform-origin: center center -100px;
-webkit-animation: spin 60s infinite linear;
-moz-animation: spin 60s infinite linear;
-o-animation: spin 60s infinite linear;
animation: spin 60s infinite linear;
}
.sphere div {
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
}
#-webkit-keyframes spin {
010.00% {-webkit-transform: rotateX( 0deg) rotateY( 360deg) rotateZ( 0deg);}
020.00% {-webkit-transform: rotateX( 360deg) rotateY( 360deg) rotateZ( 0deg);}
030.00% {-webkit-transform: rotateX( 720deg) rotateY( 720deg) rotateZ( 0deg);}
100.00% {-webkit-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
#-moz-keyframes spin {
010.00% {-moz-transform: rotateX( 0deg) rotateY( 360deg) rotateZ( 0deg);}
020.00% {-moz-transform: rotateX( 360deg) rotateY( 360deg) rotateZ( 0deg);}
030.00% {-moz-transform: rotateX( 720deg) rotateY( 720deg) rotateZ( 0deg);}
100.00% {-moz-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
#-o-keyframes spin {
010.00% {-o-transform: rotateX( 0deg) rotateY( 360deg) rotateZ( 0deg);}
020.00% {-o-transform: rotateX( 360deg) rotateY( 360deg) rotateZ( 0deg);}
030.00% {-o-transform: rotateX( 720deg) rotateY( 720deg) rotateZ( 0deg);}
100.00% {-o-transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
#keyframes spin {
010.00% {transform: rotateX( 0deg) rotateY( 360deg) rotateZ( 0deg);}
020.00% {transform: rotateX( 360deg) rotateY( 360deg) rotateZ( 0deg);}
030.00% {transform: rotateX( 720deg) rotateY( 720deg) rotateZ( 0deg);}
100.00% {transform: rotateX(2880deg) rotateY(3240deg) rotateZ(2520deg);}
}
input, input~ label {
cursor: pointer;
}
input:checked~ label {
color: #f77;
}
.show-geometry div {
background: rgba(160, 160, 160, 0.5) !important;
border: 1px solid #333;
-webkit-backface-visibility: visible;
-moz-backface-visibility: visible;
-o-backface-visibility: visible;
backface-visibility: visible;
}
<input id="show-geometry" type="checkbox" onchange="showGeometry(this);">
<label for="show-geometry">Show geometry</label>
Sphere like shape
There is no actual 3D shapes in html5
But you can stack 2D shapes on top of each other.
With this in mind you can create pretty a close representation of a sphere.
.container {
perspective: 1000px;
//transform-style: preserve-3d;
width: 300px;
height: 300px;
border: 5px solid pink;
}
.circ {
transform-style: preserve-3d;
border: 5px solid firebrick;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform-origin: center;
transform: translateX(-50%) translateY(-50%);
transition: transform 2s linear;
}
.circ:nth-of-type(1) {
height: 10%;
width: 10%;
transform: translateX(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-55px);
}
.circ:nth-of-type(2) {
height: 20%;
width: 20%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-45px);
}
.circ:nth-of-type(3) {
height: 30%;
width: 30%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-25px);
}
.circ:nth-of-type(4) {
height: 40%;
width: 40%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(-10px);
}
.circ:nth-of-type(5) {
height: 40%;
width: 40%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(10px);
}
.circ:nth-of-type(6) {
height: 30%;
width: 30%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(25px);
}
.circ:nth-of-type(7) {
height: 20%;
width: 20%;
transform: translatex(-50%) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(45px);
}
.circ:nth-of-type(8) {
height: 10%;
width: 10%;
transform: translatex(calc(-50%)) translateY(-50%) rotateX(40deg) rotateY(40deg) translateZ(55px);
}
/*ANIMATION*/
.container:hover .circ:nth-of-type(1) {
transform: translateX(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-60px);
}
.container:hover .circ:nth-of-type(2) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-40px);
}
.container:hover .circ:nth-of-type(3) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(-20px);
}
.container:hover .circ:nth-of-type(4) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(0px);
}
.container:hover .circ:nth-of-type(5) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(20px);
}
.container:hover .circ:nth-of-type(6) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(40px);
}
.container:hover .circ:nth-of-type(7) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(60px);
}
.container:hover .circ:nth-of-type(8) {
transform: translatex(-50%) translateY(-50%) rotateX(180deg) rotateY(40deg) translateZ(70px);
}
.container:hover {
background-color: #f2f2f2;
}
<div class="container">
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
</div>
#cont {
perspective: 10000px;
transform-style: preserve-3d;
-webkit-animation: rotat 1s linear infinite;
animation: rotat 10s linear infinite;
transform-origin: 50% 50% 50%;
}
.circ {
height: 200px;
width: 200px;
border: 2px solid black;
border-radius: 50%;
position: absolute;
top: 50px;
left: 50%;
margin-left: -100px;
transform-origin: 50%;
transform-style: preserve-3d;
background: orange;
}
.circ:nth-child(1) {
transform: rotateX(0deg);
}
.circ:nth-child(2) {
transform: rotateX(30deg);
}
.circ:nth-child(3) {
transform: rotateX(60deg);
}
.circ:nth-child(4) {
transform: rotateX(90deg);
}
.circ:nth-child(5) {
transform: rotateX(120deg);
}
.circ:nth-child(6) {
transform: rotateX(150deg);
}
.circ:nth-child(7) {
transform: rotateX(180deg);
}
/*other side rotated*/
.circ:nth-child(8) {
transform: rotateY(30deg);
}
.circ:nth-child(9) {
transform: rotateY(60deg);
}
.circ:nth-child(10) {
transform: rotateY(90deg);
}
.circ:nth-child(11) {
transform: rotateY(120deg);
}
.circ:nth-child(12) {
transform: rotateY(150deg);
}
.circ:nth-child(13) {
transform: rotateY(180deg);
}
.oth {
background: crimson;
}
#-webkit-keyframes rotat {
0% {
-webkit-transform: rotateY(0deg) translateX(0);
}
100% {
-webkit-transform: rotateY(360deg);
}
}
#keyframes rotat {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
<div id="cont">
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<div class="circ"></div>
<!--rotated other side-->
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
<div class="circ oth"></div>
</div>

Webkit 3D perspective bugs

I'm playing around with browsers lately, and now I'm fighting with 3D. WebGL is awesome, and I can do 3D in CSS3 too? Even better! Ok, so my vision was to create floating 3D objects using nested transformations (with preserve-3d).
HTML
<div class="scene">
<div class="box">
<div class="side_1"></div>
<div class="side_2"></div>
<div class="side_3"></div>
<div class="side_4"></div>
<div class="side_5"></div>
<div class="side_6"></div>
</div>
<div class="box">
<div class="side_1"></div>
<div class="side_2"></div>
<div class="side_3"></div>
<div class="side_4"></div>
<div class="side_5"></div>
<div class="side_6"></div>
</div>
<div class="box">
<div class="side_1"></div>
<div class="side_2"></div>
<div class="side_3"></div>
<div class="side_4"></div>
<div class="side_5"></div>
<div class="side_6"></div>
</div>
<div class="box">
<div class="side_1"></div>
<div class="side_2"></div>
<div class="side_3"></div>
<div class="side_4"></div>
<div class="side_5"></div>
<div class="side_6"></div>
</div>
</div>
CSS (I'm using prefixfree)
.scene {
perspective: 3500;
perspective-origin: 25% 100%;
animation: spin 15s infinite linear;
transform-style: preserve-3d;
width: 960px;
height: 350px;
margin: 80px auto;
}
.box {
width: 150px;
height: 180px;
position: absolute;
transform-style: preserve-3d;
top: 40px;
}
.box div {
width: 150px;
height: 180px;
opacity: 0.75;
background-color: #bada55;
position: absolute;
}
.box .side_1 {
transform: rotateY( 0deg ) translateZ( 75px );
background-color: #FF0;
}
.box .side_2 {
transform: rotateX( 180deg ) translateZ( 75px );
background-color: #F00;
}
.box .side_3 {
transform: rotateY( 90deg ) translateZ( 75px );
background-color: #CCC; }
.box .side_4 {
transform: rotateY( -90deg ) translateZ( 75px );
background-color: #000;
}
.box .side_5 {
height: 150px;
width: 150px;
background-color: #00a2ff;
transform: rotateX( 90deg ) translateZ( 75px ); }
.box .side_6 {
height: 150px;
background-color: #00a2ff;
width: 150px;
transform: rotateX( -90deg ) translateZ( 105px ); }
.box:first-child {
position: absolute;
top: 40px;
}
.box:last-child {
right: 0;
}
.box:nth-child(2) {
background: url(../img/dot.jpg) repeat-y center center transparent;
transform: translateZ( -600px );
left: 480px;
}
.box:nth-child(3) {
background: url(../img/dot.jpg) repeat-y center center transparent;
transform: translateZ( 600px );
left: 480px;
}
#keyframes spin {
0% { transform: rotateY(0); }
100% { transform: rotateY(360deg); }
}
Everything is set up, and works. But wait, what is happening? Why does the far object is bigger than close one? I don't understand. Is it webkit bug, or I'm missing something?
http://stretchbox.org/projects/Nextgen/floaters.php - here you have an example.
.scene is also rotating, so you need to apply the perspective and perspective-origin on its parent, which in your case would be body.
body {
perspective: 3500;
perspective-origin: 25% 100%;
}
You can see a demo here:
http://jsfiddle.net/dw58P/embedded/result/
Nice project by the way!