具有阻尼的物体旋转在整圆上跳跃

时间:2016-01-06 22:57:56

标签: algorithm animation

方程很简单:

rotation += deltaRotation / SPEED

这样我们就可以获得很好的减速旋转运动。然而,问题出现了,我们达到了Math.PI和-Math.PI之间的差距 - 请参阅动作片动作示例的片段。



const SPEED = 0.05;
let div = document.querySelector('div');
let targetRotation = 0;
let rotation = 0;

function rotate(dt) {
  let deltaRotation = targetRotation - rotation;
  rotation += deltaRotation * SPEED;

  div.style.transform = 'rotate(' + rotation + 'deg)';

  requestAnimationFrame(rotate);
}

document.addEventListener('mousemove', function(e) {
  targetRotation = Math.atan2(e.y - 150, e.x - 150) * 180 / Math.PI;
}, false);

requestAnimationFrame(rotate);

div {
  width: 100px;
  height: 100px;
  background: linear-gradient(45deg, #BADA55, red);
  transform: rotate(0);
  margin: 50px;
}

<div></div>
&#13;
&#13;
&#13;

可以采取哪些措施来防止此类行为?

1 个答案:

答案 0 :(得分:1)

您需要做的就是通过加上或减去2π来调整targetRotation的值,以便targetRotation - rotation的绝对值始终小于π:

if (Math.abs(deltaRotation) > Math.PI) {
  deltaRotation -= 2 * Math.PI * Math.sign(deltaRotation);
}

这是一个修改后的代码段,展示了它的工作原理。 (我已将let替换为var以支持Chrome和Firefox浏览器。)

const SPEED = 0.05;
var div = document.querySelector('div');
var targetRotation = Math.PI - 0.1;
var rotation = 0;

function rotate(dt) {
  var deltaRotation = (targetRotation - rotation) % (Math.PI * 2);
  if (Math.abs(deltaRotation) > Math.PI) {
    deltaRotation -= 2 * Math.PI * Math.sign(deltaRotation);
  }
  rotation += deltaRotation * SPEED;
  div.style.transform = 'rotate(' + rotation + 'rad)';
  requestAnimationFrame(rotate);
}

document.addEventListener('mousemove', function(e) {
  targetRotation = Math.atan2(e.y - 65, e.x - 100);
}, false);

requestAnimationFrame(rotate);
div {
  width: 30px;
  height: 100px;
  background: linear-gradient(45deg, #BADA55, red);
  transform: rotate(0);
  margin: 50px;
}
<div></div>