jQuery:如何使一个 div 元素旋转动画?

33

我可以用CSS和jQuery .rotate旋转一个div,但是我不知道如何对它进行动画处理。


什么样的动画?jQuery内置了几种动画。甚至还有一些使用CSS 3的动画。 - Jason McCreary
就像你使用.animate时一样,给它不同的CSS属性...比如我想让它旋转到新的位置。 - NullVoxPopuli
提供一个例子会很有帮助来回答你的问题。如果可以的话,请提供一个例子。 - user372551
1
我只想要一个带有任何内容的div元素进行旋转。但是希望以动画的形式展示旋转效果,就像在现实生活中用手做一样... =\ - NullVoxPopuli
看看这个jQuery补丁:http://www.zachstronaut.com/posts/2009/08/07/jquery-animate-css-rotate-scale.html 看起来应该能解决问题! - Matt Diamond
8个回答

27
利用WebkitTransform / -moz-transform: rotate(Xdeg)。这在IE中不起作用,但Matt的zachstronaut解决方案在IE中也不起作用。
如果您还想支持IE,您需要研究使用像我相信Raphael does那样的canvas
这是一个简单的jQuery代码片段,可以旋转jQuery对象中的元素。旋转可以启动和停止:

$(function() {
    var $elie = $("img"), degree = 0, timer;
    rotate();
    function rotate() {
        
        $elie.css({ WebkitTransform: 'rotate(' + degree + 'deg)'});  
        $elie.css({ '-moz-transform': 'rotate(' + degree + 'deg)'});                      
        timer = setTimeout(function() {
            ++degree; rotate();
        },5);
    }
    
    $("input").toggle(function() {
        clearTimeout(timer);
    }, function() {
        rotate();
    });
}); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<input type="button" value=" Toggle Spin " />
<br/><br/><br/><br/>
<img src="http://i.imgur.com/ABktns.jpg" />


@Steve 感谢您将 jsfiddle 转换为此代码片段。太棒了! - Peter Ajtai
确实是个很棒的答案,但在jQuery 1.8中显然更容易:https://dev59.com/-W865IYBdhLWcg3wfemU#14016604 - Michael Scheper

14
如果你设计的是 iOS 设备或者只是 WebKit,你可以完全不使用 JS 来实现:
CSS:
@-webkit-keyframes spin {  
from {  
    -webkit-transform: rotate(0deg);  
}  
to {  
    -webkit-transform: rotate(360deg);  
    } 
}

.wheel {
    width:40px;
    height:40px;
    background:url(wheel.png);
    -webkit-animation-name: spin; 
    -webkit-animation-iteration-count: infinite; 
    -webkit-animation-timing-function: linear;
    -webkit-animation-duration: 3s; 
}

这会在加载时触发动画。如果你想在悬停时触发它,可能是这样的:

.wheel {
    width:40px;
    height:40px;
    background:url(wheel.png);
}

.wheel:hover {
    -webkit-animation-name: spin; 
    -webkit-animation-iteration-count: infinite; 
    -webkit-animation-timing-function: ease-in-out;
    -webkit-animation-duration: 3s; 
}

4
@khaled_webdev这就是我说“如果你正在为iOS设备或仅为Webkit设计”的原因。 - inorganik

10

我一直在使用

$.fn.rotate = function(degrees, step, current) {
    var self = $(this);
    current = current || 0;
    step = step || 5;
    current += step;
    self.css({
        '-webkit-transform' : 'rotate(' + current + 'deg)',
        '-moz-transform' : 'rotate(' + current + 'deg)',
        '-ms-transform' : 'rotate(' + current + 'deg)',
        'transform' : 'rotate(' + current + 'deg)'
    });
    if (current != degrees) {
        setTimeout(function() {
            self.rotate(degrees, step, current);
        }, 5);
    }
};

$(".r90").click(function() { $("span").rotate(90) });
$(".r0").click(function() { $("span").rotate(0, -5, 90) });
span { display: inline-block }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<span>potato</span>

<button class="r90">90 degrees</button>
<button class="r0">0 degrees</button>


不错!但在jQuery 1.8中,显然有一种更简单的方法:https://dev59.com/-W865IYBdhLWcg3wfemU#14016604 - Michael Scheper

8
如果您只想使用jQuery选项,以下代码将起到作用:
$(el).stop().animate(
  {rotation: 360},
  {
    duration: 500,
    step: function(now, fx) {
      $(this).css({"transform": "rotate("+now+"deg)"});
    }
  }
);

这适用于jQuery 1.8版本,它会自动处理CSS前缀。由于jQuery无法实现旋转动画,因此我将transform:rotate()放在自定义的step函数中。它可能只能从0开始工作。
演示:http://jsfiddle.net/forresto/ShUgD/ IE9和Mobile Safari 4支持CSS变换但不支持CSS过渡效果,所以我想出了这个简单的补丁,使用Modernizr功能测试:
if (Modernizr.csstransitions) {
  $(el).css({
    "transition": "all 500ms ease-in-out"
  });
}

$(el).click(function(){
  var rotateTo = 360;
  if (Modernizr.csstransitions) {
    $(el).css({"transform": "rotate("+rotateTo+"deg)"});
  } else {
    $(el).stop().animate(
      {rotation: rotateTo},
      {
        duration: 500,
        step: function(now, fx) {
          $(this).css({"transform": "rotate("+now+"deg)"});
        }
      }
    );
  }
});

上述内容将在可用时使用CSS过渡效果。

4

目前,您仍然不能使用jQuery来动画旋转,但是您可以使用CSS3动画,然后只需使用jQuery添加和删除类以使动画发生。

JSFiddle演示


HTML

<img src="http://puu.sh/csDxF/2246d616d8.png" width="30" height="30"/>

CSS3

img {
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
transition-duration:0.4s;
}

.rotate {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
transition-duration:0.4s;
}

jQuery

$(document).ready(function() {
    $("img").mouseenter(function() {
        $(this).addClass("rotate");
    });
    $("img").mouseleave(function() {
        $(this).removeClass("rotate");
    });
});

3

参考Peter Ajtai的答案,这里提供一个小型jquery插件,可能会对其他人有所帮助。我没有在Opera和IE9上进行测试,但它应该也能在这些浏览器上运行。

$.fn.rotate = function(until, step, initial, elt) {
    var _until = (!until)?360:until;
    var _step = (!step)?1:step;
    var _initial = (!initial)?0:initial;
    var _elt = (!elt)?$(this):elt;

    var deg = _initial + _step;

    var browser_prefixes = ['-webkit', '-moz', '-o', '-ms'];
    for (var i=0, l=browser_prefixes.length; i<l; i++) {
      var pfx = browser_prefixes[i]; 
      _elt.css(pfx+'-transform', 'rotate('+deg+'deg)');
    }

    if (deg < _until) {
      setTimeout(function() {
          $(this).rotate(_until, _step, deg, _elt); //recursive call
      }, 5);
    }
};

$('.my-elt').rotate()

但是如果旋转角度为90度,从0度开始呢?如果运行rotate() -> 应该显示角度而不是旋转。 - user956584
为了能够旋转两个方向:var deg = (_initial < _step) ? _initial + _step : _initial - _step;此外,Jquery现在自动进行前缀处理。 - forresto
这个解决方案的主要问题是它不像$.animate()那样基于时间进行动画处理,因此将旋转180º所需的时间是旋转90º所需时间的两倍。 - forresto

2
这对我有用:
function animateRotate (object,fromDeg,toDeg,duration){
    var dummy = $('<span style="margin-left:'+fromDeg+'px;">')
    $(dummy).animate({
        "margin-left":toDeg+"px"
    },{
        duration:duration,
        step: function(now,fx){
            $(object).css('transform','rotate(' + now + 'deg)');
        }
    });
};

这比其他任意起始位置的解决方案要好得多!干得好 :)。 - Joseph Astrahan

0

我需要旋转一个对象,但是需要一个回调函数。受到John Kern答案的启发,我创建了这个。

function animateRotate (object,fromDeg,toDeg,duration,callback){
        var dummy = $('<span style="margin-left:'+fromDeg+'px;">')
        $(dummy).animate({
            "margin-left":toDeg+"px"
        },
        {
            duration:duration,
            step: function(now,fx){
                $(object).css('transform','rotate(' + now + 'deg)');
                if(now == toDeg){
                    if(typeof callback == "function"){
                        callback();
                    }
                }
            }
        }
    )};

通过这样做,您可以简单地在对象上调用旋转,例如...(在我的情况下,我正在对已经默认旋转为270度的披露三角形图标进行旋转,并将其另外旋转90度至1000毫秒的360度。最后一个参数是动画完成后的回调函数。)
animateRotate($(".disclosure_icon"),270,360,1000,function(){
                alert('finished rotate');
            });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接