Search code examples
javascriptanimationrotationaframe

Why doesn't the A-Frame camera animation always rotate along the shortest path?


I set up a virtual tour and added a few animated camera movements (I do know it is not recommended in VR, but this is just a desktop project, no VR, just point and click with the mouse cursor).

Most of the times, the camera rotates from its current position to its destination, following the shortest possible path. But other times, it just takes the longest path, which is not desired at all.

Why does this happen? And is there something I can do about it?

Here's my code: JSFiddle

And here's how you can reproduce the behavior:

From the starting position, press the enter key to rotate the camera (it will take the longest path). From there, press the space key to rotate it again, pointing it at yet another location (again, it will take the longest path).

var myCam = document.querySelector("a-camera");
document.addEventListener("keydown", event => {
  if (event.keyCode == 13) {
    myCam.setAttribute("animation", "property: rotation; to: -4.68 -210.55 0; loop: false; dur: 2000; startEvents: lookAtSomething");
    myCam.emit('lookAtSomething');
    myCam.components["look-controls"].pitchObject.rotation.x = -0.08168140899333462;
    myCam.components["look-controls"].yawObject.rotation.y = -3.674790740074061;
  } else if (event.keyCode == 32) {
    myCam.setAttribute("animation", "property: rotation; to: -2.30 59.36 0; loop: false; dur: 2000; startEvents: lookAtSomething");
    myCam.emit('lookAtSomething');
    myCam.components["look-controls"].pitchObject.rotation.x = -0.04014257279586958;
    myCam.components["look-controls"].yawObject.rotation.y = 1.051735407251783;
  }
});
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<a-scene background="color: #FAFAFA">
  <a-camera id="myCam" cursor="rayOrigin:mouse" look-controls="reverseMouseDrag:true">
    <a-cursor material="color: yellow; shader: flat"></a-cursor>
  </a-camera>
  <a-sky src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Equirectangular_projection_SW.jpg/1920px-Equirectangular_projection_SW.jpg"></a-sky>
</a-scene>


Solution

  • I think it does a simple substraction and depending on the origin and destination values (with negative values for example) it can trace a long path. One way to avoid that is to make calculations before setting the animation to adapt your values. For example -210.55 is the same as 149.45 and depending on your starting point it will make a shorter path. You should experiment a few rules and see what fits best.

    I had the same problem and went with this rule before setting the "from" value of the animation attribute. It's pretty arbitrary but it worked for me.

    if (Math.abs(y_from) > 90) y_from -= 360 * Math.sign(y_from);