css3旋转过渡,不需要最短的时间 [英] css3 rotate transition, doesn't take shortest way

查看:299
本文介绍了css3旋转过渡,不需要最短的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用css3过渡来使用phonegap平滑罗盘运动。我将所需的旋转计算为从0到359的角度。

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.

问题是,当它从359变为0时,它不会顺时针旋转1度,但是相反,它逆时针旋转了359度。

The problem is, when it should go from for example 359 to 0 it doesn't turn 1 degree clockwise, but instead it turns 359 degree counter clockwise.

有没有办法告诉CSS始终采用最短的旋转方式?

Is there a way to tell css to always take the shortest way for a rotation?

推荐答案

该转换完全按照您的指示进行。

The transform is doing exactly what you tell it to.

它的起始位置为359deg,到1deg 。您希望将360度翻转回1度,即361度。转换过渡的工作方式是在值之间插值。

It starts at 359deg and goes to 1deg. You are looking to 'rollover' 360deg back to 1deg, which is really 361deg. The way the transform transitions work is that it interpolates between values.

解决您的问题的方法是制作一个包含旋转度的计数器变量:

The solution to your problem is to make a counter variable that holds the degrees of rotation:

var rot = 0;  // lets start at zero, you can apply whatever later

要应用轮播,请更改值:

To apply a rotation, change value:

rot = 359;
// note the extra brackets to ensure the expression is evaluated before
//   the string is assigned this is require in some browsers
element.style.transform = ("rotate( " + rot + "deg )");

因此,如果您这样做:

rot = 1;
element.style.transform = ("rotate( " + rot + "deg )");

它可以返回。因此,您需要查看它是否接近360或0,无论它经过了多少转。为此,请检查 element.style.transform 的值,该值仅是当前的 rot 值,然后与新的 rot 值。但是,您需要针对可能存在的旋转次数执行此操作,因此:

it goes back. So you need to see if it is closer to 360 or 0 regardless how many rotations it has been through. You do this by checking the value of element.style.transform which is just the current rot value and then comparing to the new rot value. However, you need to do this with respect to how many rotations may exist, so:

var apparentRot = rot % 360;

现在,无论旋转多少次,您都知道负值是多少等于值+ 360:

Now no matter how many spins it has had, you know how far around it is, negative values are equal to the value + 360:

if ( apparentRot < 0 ) { apparentRot += 360; } 

现在,您已经对任何负值进行了归一化,可以询问是否正旋转(在您的情况下为360度) )或否定。由于您似乎将新的旋转值指定为0-360deg,因此简化了您的问题。您可以询问新的轮换+ 360是否比新的轮换本身更接近旧值:

Now you have normalized any negative values and can ask whether a positive rotation (through 360deg in your case) or negative is needed. Since you seem to be giving the new rotation value as 0-360deg, this simplifies your problem. You can ask if the new rotation + 360 is closer to the old value than the new rotation itself:

var aR,          // what the current rotation appears to be (apparentRot shortened)
    nR,          // the new rotation desired (newRot)
    rot;         // what the current rotation is and thus the 'counter'

// there are two interesting events where you have to rotate through 0/360
//   the first is when the original rotation is less than 180 and the new one
//   is greater than 180deg larger, then we go through the apparent 0 to 359...
if ( aR < 180 && (nR > (aR + 180)) ) {
    // rotate back
    rot -= 360;
} 

//   the second case is when the original rotation is over 180deg and the new
//   rotation is less than 180deg smaller
if ( aR >= 180 && (nR <= (aR - 180)) ) {
    // rotate forward
    rot += 360;
}

除此之外,只需将新轮换的值添加到 rot 就是所需要的:

Other than this, simply adding the value of the new rotation to rot is all that is needed:

rot += (nR - aR); //  if the apparent rotation is bigger, then the difference is
                  //  'negatively' added to the counter, so the counter is
                  //  correctly kept, same for nR being larger, the difference is
                  //  added to the counter

清理一下:

var el, rot;

function rotateThis(element, nR) {
    var aR;
    rot = rot || 0; // if rot undefined or 0, make 0, else rot
    aR = rot % 360;
    if ( aR < 0 ) { aR += 360; }
    if ( aR < 180 && (nR > (aR + 180)) ) { rot -= 360; }
    if ( aR >= 180 && (nR <= (aR - 180)) ) { rot += 360; }
    rot += (nR - aR);
    element.style.transform = ("rotate( " + rot + "deg )");
}

// this is how to intialize  and apply 0
el = document.getElementById("elementYouWantToUse");
rotateThis(el, 0);

// now call function
rotateThis(el, 359);
rotateThis(el, 1);

计数器可以是正数或负数,没关系,只需使用0- 359以进行新的轮换。

The counter can go positive or negative, it doesn't matter, just use a value between 0-359 for the new rotation.

这篇关于css3旋转过渡,不需要最短的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆