css3 rotate transition, doesn't take shortest way

前端 未结 3 1398
粉色の甜心
粉色の甜心 2021-02-15 12:47

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

3条回答
  •  难免孤独
    2021-02-15 13:31

    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:

    1. The difference angle is just an angle, so we don't take into account from or to anymore
    2. Use the remainder operator to get the angle in (-360, 360); a gotcha: remainder is not the same as mathematical modulus for negative numbers
    3. Add 540, this shifts the angle to (180, 900); this gets rid of the negative values and shifts the angle by 180 degrees
    4. Take the remainder again to get our 180-shifted value to (0, 360); this is equivalent to mathematical modulus since we have eliminated negative values
    5. Subtract 180 to unshift the value to the original angle in (-180, 180)

提交回复
热议问题