css3旋转过渡,不';不要走最短的路

css3旋转过渡,不';不要走最短的路,css,cordova,rotation,transition,Css,Cordova,Rotation,Transition,我想使用css3转换来平滑使用phonegap的指南针移动。我将所需的旋转计算为从0到359的角度 问题是,当它从359转为0时,它不是顺时针转1度,而是逆时针转359度 有没有办法告诉css总是选择最短的旋转路径?看看是否可以使用负数。从-1度到0度是顺时针方向,从359度到0度是逆时针方向。变换完全按照您的指示进行 它从359度开始,到1度。您希望将360度“翻转”回1度,实际上是361度。变换变换的工作方式是在值之间插值 问题的解决方案是创建一个保持旋转度的计数器变量: var rot =

我想使用css3转换来平滑使用phonegap的指南针移动。我将所需的旋转计算为从0到359的角度

问题是,当它从359转为0时,它不是顺时针转1度,而是逆时针转359度


有没有办法告诉css总是选择最短的旋转路径?

看看是否可以使用负数。从-1度到0度是顺时针方向,从359度到0度是逆时针方向。

变换完全按照您的指示进行

它从359度开始,到1度。您希望将360度“翻转”回1度,实际上是361度。变换变换的工作方式是在值之间插值

问题的解决方案是创建一个保持旋转度的计数器变量:

var rot = 0;  // lets start at zero, you can apply whatever later
要应用旋转,请更改值:

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
值进行比较。但是,您需要根据可能存在的旋转次数来执行此操作,因此:

var apparentRot = rot % 360;
现在,不管它旋转了多少圈,你都知道它周围有多远,负值等于+360:

if ( apparentRot < 0 ) { apparentRot += 360; } 
把它清理一下:

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);
var-el,rot;
函数旋转此(元素,nR){
var-aR;
rot=rot | | 0;//如果rot未定义或为0,则设为0,否则为rot
aR=rot%360;
如果(aR<0){aR+=360;}
如果(aR<180&(nR>(aR+180)){rot-=360;}

如果(aR>=180&&(nR)如您所述,CSS转换不会在开始和结束旋转之间找到最短路径,而是在开始和结束旋转之间完全设置动画。例如,从0到720将使指南针旋转两次,而不是按您的意愿静止

解决方案是在每次更新时将旋转角度设置为与当前旋转角度最接近的等效角度

计算这个角度的函数需要处理大角度和负角度,因为罗盘可以很容易地在任意方向旋转多次

诀窍是计算旧角度和请求角度之间的差异,并将其转换为范围(
-180
180
),以便动画始终在正确方向上采用最短路径。只需将此差异添加到旧角度,即可获得新角度

function closestEquivalentAngle(from, to) {
    var delta = ((((to - from) % 360) + 540) % 360) - 180;
    return from + delta;
}
除了将差值钳制为(
-180
180
)之外,上述函数非常简单。它使用模运算来实现这一点:

  • 差角只是一个角度,所以我们不再考虑从或到
  • 使用余数运算符获取角度(
    -360
    360
    );a gotcha:余数与负数的数学模不同
  • 添加
    540
    ,这会将角度移动到(
    180
    900
    );这会去除负值并将角度移动
    180
  • 再次取余数,将
    180
    的值移位为(
    0
    360
    );这相当于数学模,因为我们已经消除了负值
  • 减去
    180
    ,将值反移位到原始角度(
    -180
    180

  • 除了aR>=0?:aR+=360;是无效语法之外,您还需要编写aR>=0?null:aR+=360;或其他任何东西,这就是解决方案感谢您捕捉到错误。我不知道关于三元运算符的情况。我已经更改了它,因为它不是必需的。建议使代码更加清晰和简洁:在规范化aR之后,您可以计算计算旋转的差异
    drot=nR-aR;
    然后你可以简单地做
    if(drot>180){drot-=360}
    if(drot<180){drot+=360}
    最后
    rot+=drot
    谢谢!我正在做一个面向用户的工作,并将
    if(aR<0)
    更改为
    if(一行
    closestAngle(from,to)=>from+((((to-from)%360)+540)%360)-180;
    :)如果你不能在一行中编写它就不是Javascript了,阿米丽特?;)我就是忍不住
    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);
    
    function closestEquivalentAngle(from, to) {
        var delta = ((((to - from) % 360) + 540) % 360) - 180;
        return from + delta;
    }