8

css3 トランジションを使用して、phonegap を使用してコンパスの動きを滑らかにしたいと考えています。目的の回転を 0 から 359 までの角度として計算します。

問題は、たとえば 359 から 0 になると、時計回りに 1 度回転せず、反時計回りに 359 度回転することです。

css に常にローテーションの最短経路を取るように指示する方法はありますか?

4

3 に答える 3

25

変換は、あなたが指示したことを正確に実行しています。

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; } 

これで、負の値を正規化したので、正の回転 (この場合は 360 度) が必要か、負の回転が必要かを尋ねることができます。新しい回転値を 0-360deg として与えているように見えるので、これは問題を単純化します。新しい回転 + 360 が新しい回転自体よりも古い値に近いかどうかを尋ねることができます。

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必要なのは、単に新しい回転の値を追加するだけです:

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 の値を使用してください。

于 2013-11-09T05:26:32.367 に答える
0

負の数を使用できるかどうかを確認します。-1 度から 0 度までは時計回り、359 度から 0 度までは反時計回りです。

于 2013-10-27T13:50:11.703 に答える