1. ホーム
  2. jquery

[解決済み] jquery.animate()によるCSS回転のクロスブラウザ化

2023-04-18 06:09:19

質問

クロスブラウザ対応のローテーション(ie9+)を作成中なのですが、以下のコードを jsfiddle

$(document).ready(function () { 
    DoRotate(30);
    AnimateRotate(30);
});

function DoRotate(d) {

    $("#MyDiv1").css({
          '-moz-transform':'rotate('+d+'deg)',
          '-webkit-transform':'rotate('+d+'deg)',
          '-o-transform':'rotate('+d+'deg)',
          '-ms-transform':'rotate('+d+'deg)',
          'transform': 'rotate('+d+'deg)'
     });  
}

function AnimateRotate(d) {

        $("#MyDiv2").animate({
          '-moz-transform':'rotate('+d+'deg)',
          '-webkit-transform':'rotate('+d+'deg)',
          '-o-transform':'rotate('+d+'deg)',
          '-ms-transform':'rotate('+d+'deg)',
          'transform':'rotate('+d+'deg)'
     }, 1000); 
}

CSSとHTMLは本当にシンプルで、デモのためだけのものです。

.SomeDiv{
    width:50px;
    height:50px;       
    margin:50px 50px;
    background-color: red;}

<div id="MyDiv1" class="SomeDiv">test</div>
<div id="MyDiv2" class="SomeDiv">test</div>

回転は .css() を使うと回転が効きますが .animate() なぜでしょうか、そしてそれを修正する方法はありますか?

ありがとうございます。

どのように解決するのですか?

CSS-Transformsは、まだjQueryでアニメーションさせることができません。このようにすることができます。

function AnimateRotate(angle) {
    // caching the object for performance reasons
    var $elem = $('#MyDiv2');

    // we use a pseudo object for the animation
    // (starts from `0` to `angle`), you can name it as you want
    $({deg: 0}).animate({deg: angle}, {
        duration: 2000,
        step: function(now) {
            // in the step-callback (that is fired each step of the animation),
            // you can use the `now` paramter which contains the current
            // animation-position (`0` up to `angle`)
            $elem.css({
                transform: 'rotate(' + now + 'deg)'
            });
        }
    });
}

ステップ・コールバックについては、こちらで詳しく解説しています。 http://api.jquery.com/animate/#step

http://jsfiddle.net/UB2XR/23/

また、jQuery 1.7以上ではcss3トランスフォームのプレフィックスは必要ありません。

更新情報

これをjQuery-pluginで包むと、もう少し楽になります。

$.fn.animateRotate = function(angle, duration, easing, complete) {
  return this.each(function() {
    var $elem = $(this);

    $({deg: 0}).animate({deg: angle}, {
      duration: duration,
      easing: easing,
      step: function(now) {
        $elem.css({
           transform: 'rotate(' + now + 'deg)'
         });
      },
      complete: complete || $.noop
    });
  });
};

$('#MyDiv2').animateRotate(90);

http://jsbin.com/ofagog/2/edit

更新情報2

の順番を変えるために少し最適化しました。 easing , durationcomplete は重要ではありません。

$.fn.animateRotate = function(angle, duration, easing, complete) {
  var args = $.speed(duration, easing, complete);
  var step = args.step;
  return this.each(function(i, e) {
    args.complete = $.proxy(args.complete, e);
    args.step = function(now) {
      $.style(e, 'transform', 'rotate(' + now + 'deg)');
      if (step) return step.apply(e, arguments);
    };

    $({deg: 0}).animate({deg: angle}, args);
  });
};

アップデート2.1

感謝 matteo の問題を指摘してくれた this -のコンテキストに問題があることを指摘しました。 callback . で修正した場合 バインド というコールバックを jQuery.proxy を各ノード上に置く。

から以前のコードにエディションを追加しています。 アップデート2 .

アップデート2.2

これは、回転を前後に切り替えるようなことをしたい場合に可能な修正です。関数にstartパラメータを追加して、この行を置き換えただけです。

$({deg: start}).animate({deg: angle}, args);

もし、これをより汎用的にする方法を知っている人がいたら、開始度を設定したいかどうかに関わらず、すべてのユースケースに対して、適切な編集を行ってください。


使用法 ...は非常に簡単です!

主に、目的の結果に到達するために2つの方法があります。しかし、最初に、引数について見てみましょう。

jQuery.fn.animateRotate(angle, duration, easing, complete)

を除いては、すべてオプションで、デフォルトにフォールバックします。 jQuery.fn.animate -のプロパティにフォールバックします。

duration: 400
easing: "swing"
complete: function () {}

第1回

この方法は短いものですが、引数を多く渡すと少し不明瞭に見えます。

$(node).animateRotate(90);
$(node).animateRotate(90, function () {});
$(node).animateRotate(90, 1337, 'linear', function () {});

2番目

引数が3つ以上ある場合は、オブジェクトを使うのが好きなので、この構文がお気に入りです。

$(node).animateRotate(90, {
  duration: 1337,
  easing: 'linear',
  complete: function () {},
  step: function () {}
});