How can I make the side elements rotate on the x-axis in this animation?

I am trying to build a spinning animation of a cube, the sides of which also rotate on their respective axis. Here's what I have so far:

http://codepen.io/Chevex/pen/pxtwj

The following CSS rules define the position of the sides before each animation:

.front {
  transform: translateZ(100px);
  background-color: #0f0;
}
.back {
  transform: rotateY(180deg) translateZ(100px);
  background-color: #f00;
}
.right {
  transform: rotateY(90deg) translateZ(100px);
  background-color: #00f;
}
.left {
  transform: rotateY(-90deg) translateZ(100px);
  background-color: #ff0;
}
.top {
  transform: rotateX(90deg) translateZ(100px);
  background-color: #0ff;
}
.bottom {
  transform: rotateX(-90deg) translateZ(100px);
  background-color: #f0f;
}

      

This works great and positions the elements accordingly. Then I use the GSAP animation library to rotate the whole cube:

TweenMax.to($('.cube'), 7, { rotationY: 360, repeat: -1, ease: Linear.easeNone });

      

After that, I'll animate the front and back sides so that they rotate about the Z axis:

TweenMax.to($('.front, .back'), 2, { rotationZ: 360, repeat: -1, ease: Linear.easeNone });

      

Further from above and below along the Y-axis:

TweenMax.to($('.top, .bottom'), 2, { rotationY: 360, repeat: -1, ease: Linear.easeNone });

      

So far so good. The left and right sides should now rotate along the X axis:

TweenMax.to($('.right, .left'), 2, { rotationX: 360, repeat: -1, ease: Linear.easeNone });

      

Now there is a problem. For some reason, they appear to rotate on the Z-axis. I've tried rotating them on all 3 axes, but they don't seem to rotate like rolling coins like the other sides did. I thought it was a GSAP bug, but I have applied the following CSS animations to these sides manually and the same problem exists.

.right {
  transform: rotateY(90deg) translateZ(100px);
  background-color: #00f;
  -webkit-animation: spinRight 2s linear infinite;
}
.left {
  transform: rotateY(-90deg) translateZ(100px);
  background-color: #ff0;
  -webkit-animation: spinLeft 2s linear infinite;
}

@-webkit-keyframes spinRight {
  from {
    transform: rotateY(90deg) translateZ(100px) rotateX(0deg);
  }
  to {
    transform: rotateY(90deg) translateZ(100px) rotateX(360deg);
  }
}

@-webkit-keyframes spinLeft {
  from {
    transform: rotateY(-90deg) translateZ(100px) rotateX(0deg);
  }
  to {
    transform: rotateY(-90deg) translateZ(100px) rotateX(360deg);
  }
}

      

Any ideas why this is so? How can I make the left and right sides of the cube rotate the way everyone else rotates?

+3


source to share


1 answer


Yes, you are locked by curtain} , the rotateX value must be placed before the rotation. Order is important for transformations.

What happens in your case is that 90-degree (positive or negative) Y rotations rotate the X-axis to Z (or -Z-axis). Usually when you have all 3, the order of X, Y and Z will keep things straight for X, but Z will block the gimbal when Y is +/- 90 or 270. Putting X after Y, you rotate it in the Z axis (in that order, it is "inside" the Y-axis).

Try the following:

@-webkit-keyframes spinRight {
  from {
    transform: rotateX(0deg) rotateY(90deg) translateZ(100px);
  }
  to {
    transform: rotateX(360deg) rotateY(90deg) translateZ(100px);
  }
}

@-webkit-keyframes spinLeft {
  from {
    transform: rotateX(0deg) rotateY(-90deg) translateZ(100px);
  }
  to {
    transform: rotateX(360deg) rotateY(-90deg) translateZ(100px);
  }
}

      

If that doesn't do the trick, try inserting a div and rotating that div Z axis. CSS has a limited 3d ability as the gimbal is a huge problem. Also, rotate3d is limited due to the 360 ​​degree periods of sine and cosine waves (pertains to the mathematics defining the matrix). For matrix math, Sylvester works, or you can check out three.js , which has its own quirks , to deal with the stated limitations (I believe Google used three for their Rubik cube).


Edit question author:

This answer was correct. The Greensock people wanted me to nest my side elements in the parent elements and change the axis of the parent. It may have worked, but my initial attempts just caused other problems. Having done a little with Gimbal Lock , I realized that this is how the axis changes that causes the lock. I had the idea to get to the same position, but manipulating the axis in a different way. It worked and this is the result:



http://codepen.io/Chevex/pen/pxtwj

Instead:

TweenMax.set('.right', { rotationY: 90, x: '100px' });
TweenMax.set('.left', { rotationY: -90, x: '100px' });

      

I sat down and followed the axis in my head and came up with a new way to get the item in one place.

TweenMax.set('.right', { rotationZ: 90, rotationY: 90, rotationX: 90, x: '100px' });
TweenMax.set('.left', { rotationZ: -90, rotationY: -90, rotationX: 90, x: '100px' });

      

After that I was able to animate the Y axis and get the expected result now that the Y axis is pointing in the direction I originally expected the X axis to be pointing.

TweenMax.to('.right, .left', gearSpeed, { rotationY: 360, repeat: -1, ease: Linear.easeNone });

      

+3


source







All Articles