I want to use a css3 transition to smooth a compass movement using phonegap. i calculate the desired rotation as angle from 0 to 359.
The problem is, when it should go f
As you mention, the CSS transition does not find the shortest path between the starting and ending rotations, but animates fully between the starting and ending rotation. For example, going from 0 to 720 will cause the compass to animate spinning twice, rather than standing still as you desire.
The solution is on each update to set the rotation angle to the closest equivalent angle to the current rotation angle.
The function to calculate this angle needs to handle large angles and negative angles, since the compass can easily spin multiple time in either direction.
The trick is to calculate the difference between the old and requested angles and transform it into the range (-180
, 180
) so that the animation always takes the shortest path in the correct direction. You simply add this difference to the old angle to get the new angle.
function closestEquivalentAngle(from, to) {
var delta = ((((to - from) % 360) + 540) % 360) - 180;
return from + delta;
}
The above function is pretty simple aside from clamping the difference to (-180
, 180
). It makes use of modulus arithmetic to do this:
-360
, 360
); a gotcha: remainder is not the same as mathematical modulus for negative numbers540
, this shifts the angle to (180
, 900
); this gets rid of the negative values and shifts the angle by 180
degrees180
-shifted value to (0
, 360
); this is equivalent to mathematical modulus since we have eliminated negative values180
to unshift the value to the original angle in (-180
, 180
)