动画元素转换旋转

如何使用 jQuery 的 .animate()旋转元素?我正在使用下面的行,它正在正确地动画不透明度,但是它支持 CSS3转换吗?

$(element).animate({
opacity: 0.25,
MozTransform: 'rotate(-' + -amount + 'deg)',
transform: 'rotate(' + -amount + 'deg)'
});
214042 次浏览

As far as I know, basic animates can't animate non-numeric CSS properties.

I believe you could get this done using a step function and the appropriate css3 transform for the users browser. CSS3 transform is a bit tricky to cover all your browsers in (IE6 you need to use the Matrix filter, for instance).

EDIT: here's an example that works in webkit browsers (Chrome, Safari): http://jsfiddle.net/ryleyb/ERRmd/

If you wanted to support IE9 only, you could use transform instead of -webkit-transform, or -moz-transform would support FireFox.

The trick used is to animate a CSS property we don't care about (text-indent) and then use its value in a step function to do the rotation:

$('#foo').animate(
..
step: function(now,fx) {
$(this).css('-webkit-transform','rotate('+now+'deg)');
}
...

Ryley's answer is great, but I have text within the element. In order to rotate the text along with everything else, I used the border-spacing property instead of text-indent.

Also, to clarify a bit, in the element's style, set your initial value:

#foo {
border-spacing: 0px;
}

Then in the animate chunk, your final value:

$('#foo').animate({  borderSpacing: -90 }, {
step: function(now,fx) {
$(this).css('transform','rotate('+now+'deg)');
},
duration:'slow'
},'linear');

In my case, it rotates 90 degrees counter-clockwise.

Here is the live demo.

To add to the answers of Ryley and atonyc, you don't actually have to use a real CSS property, like text-index or border-spacing, but instead you can specify a fake CSS property, like rotation or my-awesome-property. It might be a good idea to use something that does not risk becoming an actual CSS property in the future.

Also, somebody asked how to animate other things at the same time. This can be done as usual, but remember that the step function is called for every animated property, so you'll have to check for your property, like so:

$('#foo').animate(
{
opacity: 0.5,
width: "100px",
height: "100px",
myRotationProperty: 45
},
{
step: function(now, tween) {
if (tween.prop === "myRotationProperty") {
$(this).css('-webkit-transform','rotate('+now+'deg)');
$(this).css('-moz-transform','rotate('+now+'deg)');
// add Opera, MS etc. variants
$(this).css('transform','rotate('+now+'deg)');
}
}
});

(Note: I can't find the documentation for the "Tween" object in the jQuery documentation; from the animate documentation page there is a link to http://api.jquery.com/Types#Tween which is a section that doesn't appear to exist. You can find the code for the Tween prototype on Github here).

In my opinion, jQuery's animate is a bit overused, compared to the CSS3 transition, which performs such animation on any 2D or 3D property. Also I'm afraid, that leaving it to the browser and by forgetting the layer called JavaScript could lead to spare CPU juice - specially, when you wish to blast with the animations. Thus, I like to have animations where the style definitions are, since you define functionality with JavaScript. The more presentation you inject into JavaScript, the more problems you'll face later on.

All you have to do is to use addClass to the element you wish to animate, where you set a class that has CSS transition properties. You just "activate" the animation, which stays implemented on the pure presentation layer.

.js

// with jQuery
$("#element").addClass("Animate");


// without jQuery library
document.getElementById("element").className += "Animate";

One could easly remove a class with jQuery, or remove a class without library.

.css

#element{
color      : white;
}


#element.Animate{
transition        : .4s linear;
color             : red;
/**
* Not that ugly as the JavaScript approach.
* Easy to maintain, the most portable solution.
*/
-webkit-transform : rotate(90deg);
}

.html

<span id="element">
Text
</span>

This is a fast and convenient solution for most use cases.

I also use this when I want to implement a different styling (alternative CSS properties), and wish to change the style on-the-fly with a global .5s animation. I add a new class to the BODY, while having alternative CSS in a form like this:

.js

$("BODY").addClass("Alternative");

.css

BODY.Alternative #element{
color      : blue;
transition : .5s linear;
}

This way you can apply different styling with animations, without loading different CSS files. You only involve JavaScript to set a class.

//this should allow you to replica an animation effect for any css property, even //properties //that transform animation jQuery plugins do not allow


function twistMyElem(){
var ball = $('#form');
document.getElementById('form').style.zIndex = 1;
ball.animate({ zIndex : 360},{
step: function(now,fx){
ball.css("transform","rotateY(" + now + "deg)");
},duration:3000
}, 'linear');
}

I stumbled upon this post, looking to use CSS transform in jQuery for an infinite loop animation. This one worked fine for me. I don't know how professional it is though.

function progressAnim(e) {
var ang = 0;


setInterval(function () {
ang += 3;
e.css({'transition': 'all 0.01s linear',
'transform': 'rotate(' + ang + 'deg)'});
}, 10);
}

Example of using:

var animated = $('#elem');
progressAnim(animated)

Just use CSS transitions:

$(element).css( { transition: "transform 0.5s",
transform:  "rotate(" + amount + "deg)" } );


setTimeout( function() { $(element).css( { transition: "none" } ) }, 500 );

As example I set the duration of the animation to 0.5 seconds.

Note the setTimeout to remove the transition css property after the animation is over (500 ms)


For readability I omitted vendor prefixes.

This solution requires browser's transition support off course.