为什么我的3D立方体不能按预期旋转?

时间:2016-07-15 16:51:26

标签: javascript jquery html css3 css-transforms

我正在做一个3D骰子,当你滑动它的脸时会旋转。问题是它在某些情况下表现得非常奇怪。例如,如果您运行代码段并向左滑动两次然后向下滑动,则会进行疯狂的旋转......

以下是代码:

$(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>

编辑:此链接:http://greensock.com/forums/topic/7811-3d-rotation-fixed-axsis/表示轮换顺序很重要。我稍微改变了我的代码,但它一直意外地旋转......

2 个答案:

答案 0 :(得分:4)

首先:设置transform"X"的{​​{1}}种不同方式导致大规模旋转。我把它们改为:

"Y"

如果您认为您希望立方体始终沿滑动方向旋转。如果是这样继续阅读 或者如果不是 ,则需要更改的是以上代码。

秒:旋转立方体时,您正在更改方向。 x轴永远不会搞砸,但y轴和z轴在没有你真正注意的情况下进行切换。

现在您可以将$(".cube").css("transform", "rotateX(" + X + "deg) rotateY(" + Y +"deg)"); 添加到混音中:

rotateZ

我已更改此CodePen中的代码here以提供示例。 我还没有完成它,因为我已经透露了这个问题,但是没有时间来完善它。

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

您需要检查y轴($(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; } } }); )和可能的z轴,并相应地旋转y轴和z轴(+ - 90)。

这主要起作用,但在确定正确的旋转轴时需要微调。祝你好运。

答案 1 :(得分:3)

你的问题更多的是如何概念化旋转而不是任何编码错误。

如果你旋转Y(90),然后旋转X(90) - 那么当你旋转X(90)时,你的X轴旋转了90度,所以它不再是从左到右,而是进/出屏幕。所以你的东西看起来就像是在那个特定的实例中做了2d旋转。

进一步说,如果用户现在从左向右滑动,它们实际上是沿Z轴滑动,你需要旋转Z.

要解决此问题,您需要跟踪已完成的旋转,并以更动态的方式将用户界面映射到多维数据集。从左向右滑动并不总是意味着旋转Y,这意味着沿着当前从左向右定向的轴旋转。

我建议你找到一个魔方或类似物,并标记每个轴的边(例如红色边是X轴),模拟滑动,然后这样可以使事情更清晰,因为你会看到那些轴移动立方体。