87

クロスブラウザ互換のローテーション(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()。それはなぜですか、それを修正する方法はありますか?

ありがとう。

4

7 に答える 7

234

CSS 変換は、まだ 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/

そして、ところで: css3 変換に jQuery 1.7+ のプレフィックスを付ける必要はありません

アップデート

これを jQuery プラグインでラップして、生活を少し楽にすることができます。

$.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

Update2

easingdurationおよびcomplete重要でない順序にするために少し最適化しました。

$.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

-context in the complete-の問題を指摘してくれたmateoに感謝します。各ノードでコールバックをバインドして修正した場合。thiscallbackjQuery.proxy

Update 2から以前にコードにエディションを追加しました。

アップデート 2.2

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

$({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 () {}
});
于 2013-03-03T21:29:14.720 に答える
18

ありがとうございます!大きな貢献。プラグインをもう少し肉付けしました。フル コントロールおよびクロス ブラウザー CSS 用の startAngle を追加しました。

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

        $({deg: startAngle}).animate({deg: endAngle}, {
            duration: duration,
            easing: easing,
            step: function(now){
                elem.css({
                  '-moz-transform':'rotate('+now+'deg)',
                  '-webkit-transform':'rotate('+now+'deg)',
                  '-o-transform':'rotate('+now+'deg)',
                  '-ms-transform':'rotate('+now+'deg)',
                  'transform':'rotate('+now+'deg)'
                });
            },
            complete: complete || $.noop
        });
    });
};
于 2013-07-10T19:23:44.390 に答える
10

jQuery 経由で CSS3 アニメーションを扱っている場合、jQuery トランジットはおそらくあなたの人生を楽にしてくれるでしょう。

EDIT 2014年3月 (私のアドバイスは、投稿して以来、常に上下投票されているため)

最初に上記のプラグインをほのめかした理由を説明しましょう。

DOM各ステップ (つまり) で を更新する$.animateことは、パフォーマンスの点で理想的ではありません。動作しますが、純粋なCSS3 トランジションCSS3 アニメーションよりもおそらく遅くなります。

これは主に、トランジションが最初から最後までどのように表示されるかを示すと、ブラウザーが事前に考える機会を得るためです。

これを行うには、たとえば、トランジションの状態ごとに CSS クラスを作成し、jQuery のみを使用してアニメーションの状態を切り替えることができます。

ビジネス ロジックと混同するのではなく、CSS の残りの部分と一緒にアニメーションを微調整できるため、これは一般的に非常に優れています。

// initial state
.eye {
   -webkit-transform: rotate(45deg);
   -moz-transform: rotate(45deg);
   transform: rotate(45deg);
   // etc.

   // transition settings
   -webkit-transition: -webkit-transform 1s linear 0.2s;
   -moz-transition: -moz-transform 1s linear 0.2s;
   transition: transform 1s linear 0.2s;
   // etc.
}

// open state    
.eye.open {

   transform: rotate(90deg);
}

// Javascript
$('.eye').on('click', function () { $(this).addClass('open'); });

変換パラメーターのいずれかが動的である場合は、代わりに style 属性をもちろん使用できます。

$('.eye').on('click', function () { 
    $(this).css({ 
        -webkit-transition: '-webkit-transform 1s ease-in',
        -moz-transition: '-moz-transform 1s ease-in',
        // ...

        // note that jQuery will vendor prefix the transform property automatically
        transform: 'rotate(' + (Math.random()*45+45).toFixed(3) + 'deg)'
    }); 
});

MDN の CSS3 トランジションに関するより詳細な情報。

ただし、覚えておくべきことが他にもいくつかあります。複雑なアニメーションやチェーンなどがある場合、これらすべてが少し難しくなる可能性があります。jQuery Transitは、ボンネットの下ですべてのトリッキーなビットを実行するだけです。

$('.eye').transit({ rotate: '90deg'}); // easy huh ?
于 2013-03-03T21:38:16.507 に答える
2

これが私の解決策です:

var matrixRegex = /(?:matrix\(|\s*,\s*)([-+]?[0-9]*\.?[0-9]+(?:[e][-+]?[0-9]+)?)/gi;

var getMatches = function(string, regex) {
    regex || (regex = matrixRegex);
    var matches = [];
    var match;
    while (match = regex.exec(string)) {
        matches.push(match[1]);
    }
    return matches;
};

$.cssHooks['rotation'] = {
    get: function(elem) {
        var $elem = $(elem);
        var matrix = getMatches($elem.css('transform'));
        if (matrix.length != 6) {
            return 0;
        }
        return Math.atan2(parseFloat(matrix[1]), parseFloat(matrix[0])) * (180/Math.PI);
    }, 
    set: function(elem, val){
        var $elem = $(elem);
        var deg = parseFloat(val);
        if (!isNaN(deg)) {
            $elem.css({ transform: 'rotate(' + deg + 'deg)' });
        }
    }
};
$.cssNumber.rotation = true;
$.fx.step.rotation = function(fx) {
    $.cssHooks.rotation.set(fx.elem, fx.now + fx.unit);
};

その後、デフォルトのアニメーション fkt で使用できます。

//rotate to 90 deg cw
$('selector').animate({ rotation: 90 });

//rotate to -90 deg ccw
$('selector').animate({ rotation: -90 });

//rotate 90 deg cw from current rotation
$('selector').animate({ rotation: '+=90' });

//rotate 90 deg ccw from current rotation
$('selector').animate({ rotation: '-=90' });
于 2015-05-09T17:54:05.457 に答える
1

jQuery.transit は jQuery.easing と互換性がないため、別の答えです。このソリューションは、jQuery 拡張機能として提供されます。より一般的ですが、回転は特定のケースです。

$.fn.extend({
    animateStep: function(options) {
        return this.each(function() {
            var elementOptions = $.extend({}, options, {step: options.step.bind($(this))});
            $({x: options.from}).animate({x: options.to}, elementOptions);
        });
    },
    rotate: function(value) {
        return this.css("transform", "rotate(" + value + "deg)");
    }
});

使用方法は次のように簡単です。

$(element).animateStep({from: 0, to: 90, step: $.fn.rotate});
于 2017-03-22T18:57:35.550 に答える