2D转换,为什么会出现这种情况

时间:2016-05-03 13:17:21

标签: javascript css 2d transform

我有下面的代码,其中我试图设置相对于我定义的偏移量的块变换的动画。 但是,这不是一个平滑的转换,而是让这个非常奇怪的行为,它似乎是复制到三胞胎,然后加倍,然后回到三连,然后再回到单身。

我知道这是一种视错觉,但我很好奇为什么我没有在定义的点周围获得逐渐旋转的预期行为,而是获得这种推动效果。

我是2d / 3d操作的新手,我不明白它的所有数学,但我想学习它,这就是为什么我写这个,以掌握实际发生的数字与哪些数字

我正在寻找解释为什么会出现这种情况,因为它并不是我所期待的......

回顾一下:随着学位的增加,我期待逐渐轮换,而不是我在整个地方动画。我做错了什么?

function BlockPos(x,y,z) {
   this.x = x;
   this.y = y;
   this.z = z;
}
BlockPos.prototype.getX = function() {
  return this.x;
}
BlockPos.prototype.getZ = function() {
  return this.z;
}
BlockPos.prototype.getY = function() {
  return this.y;
}
BlockPos.prototype.setX = function(x) {
  this.x = x;
}
BlockPos.prototype.setZ = function(z) {
  this.z = z;
}
BlockPos.prototype.setY = function(y) {
  this.y = y;
}

function Block(color,blockpos) {
this.color = color;
this.blockpos = blockpos;
}
Block.prototype.getBlock = function() {
   return '<div style="display:inline-block;width:38px;height:38px;position:absolute;left:'+(this.blockpos.getX()*40)+'px;top:'+(this.blockpos.getZ()*40)+'px;border:1px solid gray;background-color:'+this.color+'"></div>';
}

arr = [
   new Block('green',new BlockPos(1,1,1)),
   new Block('green',new BlockPos(1,1,2)),
   new Block('green',new BlockPos(1,1,3)),
   new Block('red',new BlockPos(2,1,1)),
   new Block('red',new BlockPos(3,1,1)),
   new Block('red',new BlockPos(4,1,1)),
   new Block('red',new BlockPos(5,1,1))
];
html = '';
center = new BlockPos(0,1,0);
function rotateAroundPoint(pos, center,angle) {
//POINT rotate_point(float cx,float cy,float angle,POINT p)
  var s = Math.sin(angle);
  var c = Math.cos(angle);
  var p = new BlockPos(pos.getX(),pos.getY(),pos.getZ());
  // translate point back to origin:
  p.x -= center.getX();
  p.z -= center.getZ();

  // rotate point
  var xnew = p.x * c - p.z * s;
  var znew = p.x * s + p.z * c;

  // translate point back:
  p.x = xnew + center.getX();
  p.z = znew + center.getZ();
  return p;

}
function degreesToRadians(degrees) {
   return degrees * 3.14159265358979323846264338327950288 /180
}
function rotate(arr,center,degrees) {
    
     for(var c=0;c<arr.length;c++) {
         
         pos = rotateAroundPoint(arr[c].blockpos,center,degreesToRadians(degrees));
         

         arr[c].blockpos.setX(pos.getX());
         arr[c].blockpos.setZ(pos.getZ());

     }
     return arr;
}
var rotation = 0;
window.setInterval(function() {
  
  rotation+=1;
  if(rotation >= 360) rotation = 0;
  var html = rotation+' degrees<BR/>';
  arr = rotate(arr,center,rotation);
  for(c=0;c<arr.length;c++) {
     html += arr[c].getBlock();
  }
  $('#foo').html(html);
},50);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative;top:200px;left:200px;background-color:yellow;width:500px;height:500px;" id="foo">
</div>

2 个答案:

答案 0 :(得分:1)

问题的核心在于:

arr = rotate(arr,center,rotation);

您可以在已轮换的arr上指定轮播,并且不要在轮换功能中考虑 delta 时间。相反,你将(已经旋转的)arr旋转了经过的总时间 - 这会产生加速/积累的东西。

考虑相同的代码,增量时间为1

&#13;
&#13;
function BlockPos(x,y,z) {
   this.x = x;
   this.y = y;
   this.z = z;
}
BlockPos.prototype.getX = function() {
  return this.x;
}
BlockPos.prototype.getZ = function() {
  return this.z;
}
BlockPos.prototype.getY = function() {
  return this.y;
}
BlockPos.prototype.setX = function(x) {
  this.x = x;
}
BlockPos.prototype.setZ = function(z) {
  this.z = z;
}
BlockPos.prototype.setY = function(y) {
  this.y = y;
}

function Block(color,blockpos) {
this.color = color;
this.blockpos = blockpos;
}
Block.prototype.getBlock = function() {
   return '<div style="display:inline-block;width:38px;height:38px;position:absolute;left:'+(this.blockpos.getX()*40)+'px;top:'+(this.blockpos.getZ()*40)+'px;border:1px solid gray;background-color:'+this.color+'"></div>';
}

arr = [
   new Block('green',new BlockPos(1,1,1)),
   new Block('green',new BlockPos(1,1,2)),
   new Block('green',new BlockPos(1,1,3)),
   new Block('red',new BlockPos(2,1,1)),
   new Block('red',new BlockPos(3,1,1)),
   new Block('red',new BlockPos(4,1,1)),
   new Block('red',new BlockPos(5,1,1))
];
html = '';
center = new BlockPos(0,1,0);
function rotateAroundPoint(pos, center,angle) {
//POINT rotate_point(float cx,float cy,float angle,POINT p)
  var s = Math.sin(angle);
  var c = Math.cos(angle);
  var p = new BlockPos(pos.getX(),pos.getY(),pos.getZ());
  // translate point back to origin:
  p.x -= center.getX();
  p.z -= center.getZ();

  // rotate point
  var xnew = p.x * c - p.z * s;
  var znew = p.x * s + p.z * c;

  // translate point back:
  p.x = xnew + center.getX();
  p.z = znew + center.getZ();
  return p;

}
function degreesToRadians(degrees) {
   return degrees * 3.14159265358979323846264338327950288 /180
}
function rotate(arr,center,degrees) {
    
     for(var c=0;c<arr.length;c++) {
         
         pos = rotateAroundPoint(arr[c].blockpos,center,degreesToRadians(degrees));
         

         arr[c].blockpos.setX(pos.getX());
         arr[c].blockpos.setZ(pos.getZ());

     }
     return arr;
}
var rotation = 0;
window.setInterval(function() {
  
  rotation+=1;
  if(rotation >= 360) rotation = 0;
  var html = rotation+' degrees<BR/>';
  arr = rotate(arr,center,1);
  for(c=0;c<arr.length;c++) {
     html += arr[c].getBlock();
  }
  $('#foo').html(html);
},50);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative;top:200px;left:200px;background-color:yellow;width:500px;height:500px;" id="foo">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

就像你说的那样,这是一种视错觉。由于旋转速度如此之快,正方形在每个帧之间移动四分之一甚至三分之一的旋转,因此对于您的眼睛来说,它看起来像是对象的多个副本,因为它只是“跳”到它的新位置。你的代码没有任何问题,它只是我们的眼睛处理运动的方式。你甚至可以通过观看粉丝在现实生活中看到这一点。在某些速度下,您会看到刀片缓慢移动甚至向后移动。

相关问题