Why is my 3d cube not spinning as expected?

I make a 3D cube that rotates when you poke his face. The problem is that in some cases this is really strange. For example, if you run a fragment and swipe twice on the screen, and then swipe down on the screen, this will lead to insane rotation ...

Here is the code:

$(function() { var X = 0, Y = 0; var hammertime = new Hammer($(".thirdDimension")[0], {domEvents: true}); hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); function rotate(what) { switch (what) { case "X": $(".cube").css("transform", "rotateX(" + X + "deg) rotateY(" + Y +"deg)"); break; case "Y": $(".cube").css("transform", "rotateY(" + Y +"deg) rotateX(" + X + "deg)"); break; } $("#debug").html($("#debug").html() + $(".cube").attr("style") + "<br>").scrollTop($("#debug")[0].scrollHeight); } $(".thirdDimension").on("swipeleft", function(e){ Y -= 90; rotate("Y"); }); $(".thirdDimension").on("swiperight", function(e){ Y += 90; rotate("Y"); }); $(".thirdDimension").on("swipeup", function(e){ X += 90; rotate("X"); }); $(".thirdDimension").on("swipedown", function(e){ X -= 90; rotate("X"); }); }); 
 * { box-sizing: border-box; } html, body { height: 100%; font-family: sans-serif; } .tableContainer, .vcenter { height: 100%; width: 100%; } .tableContainer { display: table; } .vcenter { height: 100%; display: table-cell; vertical-align: middle; } .thirdDimension { perspective: 500px; perspective-origin: 50% 100px; } .cube { margin: 0 auto; position: relative; width: 200px; height: 200px; transform-style: preserve-3d; } .cube div { position: absolute; width: 200px; height: 200px; box-shadow: inset 0 0 30px black; font-size: 72pt; padding-top: 35px; text-align: center; background-color: black; } .right { transform: rotateY(-270deg) translateX(100px); transform-origin: top right; } .left { transform: rotateY(270deg) translateX(-100px); transform-origin: center left; } .up { transform: rotateX(90deg) translateY(-100px); transform-origin: top center; } .down { transform: rotateX(-90deg) translateY(100px); transform-origin: bottom center; } .front { transform: translateZ(100px); } .back { transform: translateZ(-100px) rotateY(180deg); } .cube { -webkit-transition: .3s all linear; cursor: pointer; } .cube div:after { display: block; position: absolute; width: 100px; height: 100px; content: ""; border: 1px solid; } .front:after { top: 0; right: 0; background-color: green; } .back:after { bottom: 0; right: 0; background-color: blue; } .right:after { top: 0; left: 0; background-color: red; } .left:after { bottom: 0; left: 0; background-color: DarkOrange; } .up:after { right: 0; bottom: 0; background-color: white; } .down:after { bottom: 0; left: 0; background-color: yellow; } #debug { position: fixed; background-color: cyan; overflow: auto; height: 50px; width: 100%; } /* .cube { animation: linear 5s rotate infinite; } @-webkit-keyframes rotate { 0% { transform: rotateX(0deg) rotateY(0deg); } 100% { transform: rotateX(360deg) rotateY(720deg); } } */ 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <div id='debug'></div> <div class='tableContainer'> <div class='vcenter'> <div class='thirdDimension'> <div class='cube'> <div class='up'></div> <div class='front'></div> <div class='right'></div> <div class='left'></div> <div class='back'></div> <div class='down'></div> </div> </div> </div> </div> 

EDIT: This link: http://greensock.com/forums/topic/7811-3d-rotation-fixed-axsis/ says that the rotation order matters. I changed my code a bit, but it spins unexpectedly ...

+6
source share
2 answers

First: transform settings in different ways for "X" or "Y" caused massive rotation. I changed both of them to:

 $(".cube").css("transform", "rotateX(" + X + "deg) rotateY(" + Y +"deg)"); 

If you think you want the cube to always rotate in the direction of the swipe. Keep reading if this is the case: or if not , all you had to change was the code above.


Second: When you rotate the cube, you change orientation. The x-axis is never confused, but the y-axis and z-axis are switched without much attention.

Now you can add rotateZ to the mix:

 $(".cube").css("transform", "rotateX(" + X + "deg) rotateY(" + Y +"deg) rotateZ(" + Z + "deg)"); 

I changed the code here in this CodePen to give an example. I did not finish it because I solved this problem, but I do not have time to improve it.

 $(function() { var X = 0, Y = 0, Z = 0; var hammertime = new Hammer($(".thirdDimension")[0], {domEvents: true}); hammertime.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); function rotate() { $(".cube").css("transform", "rotateX(" + X + "deg) rotateY(" + Y +"deg) rotateZ(" + Z + "deg)"); $("#debug").html($("#debug").html() + $(".cube").attr("style") + "<br>").scrollTop($("#debug")[0].scrollHeight); } $(".thirdDimension").on("swipeleft", function(e){ //Y -= 90; check(-90); rotate(); }); $(".thirdDimension").on("swiperight", function(e){ //Y += 90; check(90); rotate(); }); $(".thirdDimension").on("swipeup", function(e){ X += 90; rotate(); }); $(".thirdDimension").on("swipedown", function(e){ X -= 90; rotate(); }); function check(num) { var temp = Math.abs(X % 360); switch (temp) { case 0: console.log(temp); Y += num; break; case 90: console.log(temp); Z -= num break; case 180: console.log(temp); Y -= num; break; case 270: console.log(temp); Z -= num; break; } } }); 

You need to check the y axis ( Math.abs(Y % 360)) ) and possibly the z axis and rotate the y axis and z axis (+ - 90) accordingly.

This basically works, but requires fine tuning when determining the correct axis to rotate. Good luck.

+4
source

Your problem is how you conceptualized the rotation than any coding errors.

If you rotate Y (90), then rotate X (90) - then by the time you get rotateX (90), your X axis will rotate 90 degrees, so it will no longer remain to the right, but to / from the screen. That way your thing will look like 2d is spinning in this particular case.

And for future reference, if the user now moves left and right, they actually scroll along the Z axis, and you need to rotate Z.

To fix this, you need to track the rotation made and more dynamically map the user interface to the cube. Scrolling left and right does not always mean Y rotation, which means it rotates along the axis that is currently oriented from left to right.

I suggest you find a rubik cube or similar and mark the sides on the axis (for example, the red side is the X axis), simulate a scroll, and then this should make things clearer, since you will see that these axes are moving the cube.

+2
source

All Articles