electrofly
electrofly

Reputation: 190

Cube rotation with css

I am having a bit of an issue with rotation of a cube. I want to make it cross-browser so I am transforming every side of the cube. When I am rotating from left to right the sides align perfectly on all browsers Chrome, Firefox and IE, BUT when the cube is rotated from top to bottom, the sides align only on Chrome (If I make the animation slower on Chrome the sides are broken the same way as the other browsers, so I think working properly is a bug :D). I have provided an example on jsfiddle:

http://jsfiddle.net/0n9bnxe5/

HTML:

<div class="flip-card-content">
  <div class="flip-card-side-a" style="background:red">
    FRONT 
  </div>
  <div class="flip-card-side-b" style="background:green">
    BACK
  </div>
  <div class="flip-card-side-c" style="background:aqua">
    LEFT
  </div>
</div>
<button id="button">Flip-top</button>
<button id="button2">Filp-right</button>

CSS:

.flip-card-content {
    position: relative;
    margin: 100px;
    width: 200px;
    height: 200px;
    transform-style: preserve-3d;
    perspective:1000px;
}

.flip-card-side-a,
.flip-card-side-b,
.flip-card-side-c{
    width: 100%;
    position: absolute;
    height: 100%;
    backface-visibility: hidden;
    transform-origin:50% 50% 0px;
    transition: all .5s ease-in-out;
}

.flip-card-side-a {
  transform: rotateY(0deg) translateZ(100px);
  z-index: 1;
}
.flip-card-side-b {
  transform: rotateX(90deg) translateZ(100px);
}
.flip-card-side-c {
  transform: rotateY(-90deg) translateZ(100px);
}

.flip .flip-card-side-a {

  transform: rotateX(-90deg) translateZ(100px);
}
.flip .flip-card-side-b {
  display:block;
  transform: rotateY(0deg) translateZ(100px);
  z-index: 1;
}
.flip-right .flip-card-side-a {
  transform: rotateY(90deg) translateZ(100px);
}
.flip-

right .flip-card-side-b {
  display:none;
}
.flip-right .flip-card-side-c {
  transform: rotateY(0deg) translateZ(100px);
  z-index:1;
}

JQUERY:

$("#button").on('click', function(){
  $(".flip-card-content").removeClass("flip-right");
  setTimeout(function(){
    $(".flip-card-content").toggleClass("flip");
   },500);
});

$("#button2").on('click', function(){
  $(".flip-card-content").removeClass("flip");
  setTimeout(function(){
    $(".flip-card-content").toggleClass("flip-right");
  },500);

});

Any advice is welcomed!

Upvotes: 2

Views: 1709

Answers (2)

vals
vals

Reputation: 64264

Transition in 3d space are tricky, and different browsers can handle them differently.

Here you have your fiddle corrected.

Your best bet is to leave nothing to the browser imagination

so, instead of changing

  transform: rotateY(0deg) translateZ(100px);

to

  transform: rotateX(-90deg) translateZ(100px);

make the change happen from

  transform: rotateX(0deg) rotateY(0deg) translateZ(100px);

to

  transform: rotateX(-90deg) rotateY(0deg)  translateZ(100px);

Notice that I didn't change the transform from a mathematical point of view; but now every property matches a similar one.

Note just in case you want to know, in the first case IE is making the followng transition: change the angle of rotation from 0 to -90deg. At the same time, change the axis of rotation from Y to X. So, at the middle of the transition, the rotation is wrong (from your point of view), but in a mathematic sense, both ways of understanding the transition make sense.

Upvotes: 1

RichieAHB
RichieAHB

Reputation: 2088

Your translateZ doesn't quite work in the way you expect. Have look at how I've positioned the faces on the cube here and compare it to your own. Ultimately, I find the easiest way to rotate items such as cubes etc. is to position all the elements and then just rotate the container.

Also for nice scaling of fonts, images etc. its preferable to leave the front face at its natural size rather than scale up (i.e. move everything backward in 3d space):

.box {
    height: 100%;
    position: relative;
    transform: rotateX(0deg);
    transform-origin: 50% 50% -100px;
    transform-style: preserve-3d;
    transition: all 1s;
    width: 100%;
}

.box--rotate-top {
    transform: rotateX(-90deg);
}

.box--rotate-left {
    transform: rotateY(90deg);
}

.box__face {
    backface-visibility: hidden;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}

.box__face--front {
    background: #f90;
}

.box__face--top {
    background: #369;
    transform: rotateX(90deg) translateZ(200px);
    transform-origin: 0 100% 0;
}

.box__face--left {
    background: #867;
    transform: rotateY(-90deg) translateZ(200px);
    transform-origin: 100% 0 0;
}

Here is the fiddle.

Upvotes: 2

Related Questions