jQuery Patch: Animate CSS Rotation and Scale

I have created a monkey patch for jQuery (tested through 1.6) which enables you to independently set and/or animate both the scale and rotation of any HTML content with jQuery. This code uses the scale() and rotate() CSS transformations that are only supported by Webkit, Safari, Chrome, Firefox 3.5+, IE9, and some versions of Opera at this time.

As an example I have some spinning HTML content below. You can click the content to increase its scale while it continues to spin. Try it out:

Click me to scale up!

After applying my patch, the following jQuery code is used to create this example:

Features of this Patch:

Get and set rotate and scale CSS transforms independently with the added custom jQuery methods rotate() and scale(). These work like setting any other CSS property, i.e. you are rotating to an angle not rotating by an angle. Example syntax:

Animate rotate and scale CSS transforms independently using jQuery's animate() method. This works like any other jQuery CSS animation, i.e. you can rotate to a specific angle, or you can increase or decrease the angle of rotation by any number of degrees. Here are examples of both syntaxes:

// Rotate to 30deg and scale to 125%
$('#example').animate({rotate: '30deg', scale: '1.25'}, 1000);
// Rotate by 30deg from current position and scale down by 10%
$('#example').animate({rotate: '+=30deg', scale: '-=0.1'}, 1000);

An important note for jQuery 1.4.3+ users:As of jQuery 1.4.3, the default behavior when fetching a CSS transform property with jQuery changed. Prior to 1.4.3 the value returned was the string value of the CSS transform as defined by the user such as 'rotate(30deg)' or 'scale(1.5)'. As of 1.4.3, the value returned was a string representing the six value transformation matrix itself. Because people using this patch may have written code that relies on the older behavior, and because this animation patch relies on this older behavior, I have decided to update my patch to force 1.4.3 to return the string of the transform as defined by the user instead of the matrix. This means if you apply my patch to your jQuery 1.4.3, other people's transform code that relies on this new 1.4.3 behavior may not work. (My other option -- and something I may do in the future -- would be to internally map all string transform rules into a transformation matrix inside of my patch.)

To use this patch, load jquery-animate-css-rotate-scale.js after loading jQuery and
jquery-css-transform.js. For example:

That wouldn't be impossible Seamus. I did submit a patch to make the css() method support "transform" but the jQuery team said they were uninterested in including anything in the jQuery core that was not supported by all browsers. I suppose this is what plugins are for.

Would there be a way to make clouds that repeatedly and continuously move from one side of the screen to the other. Like an animation loop that resets and plays again? I think this can be done with the animation plugin, but I appreciate help. Thanks!

I am playing with your plugin and cannot figure out why it only executes once. I have set an object to rotate 360 degrees when clicked. It does so but then will not do it again unless the page is refreshed. No errors are registering in the error console. Is this as-designed is there a run once option set in the plugin?

Dave: It is executing more than once. The issue is that once you have rotated to the 360 degrees position, if you tell it to rotate to the 360 degrees position again, it is already there. You're setting a CSS property for the number of degrees an object is rotated... think of it as "rotate to" instead of "rotate by." (I can see how that would be confusing from the method names!)

There is a solution, though. If you look at my examples you will see that there is in fact a way to do "rotate-by" 360 degrees or any other amount:

$('#foo').animate({rotate: '+=360deg'}, 0);

There is a reason why I designed it this way, though. Consider the following jQuery:

If you write code like that you are saying you want to set the margin to 40px, not increase it by 40px. If you want to increase or decrease a CSS value from its current value in jQuery, then you use the += or -= animate syntax:

$('#foo').animate({margin: '+=40px'}, 0);

I actually added the rotate() and scale() methods as a way to set and retrieve those values of the CSS transform property. I guess I avoided making the syntax $.css('rotate') because actually 'transform' is the CSS property and rotate and scale are values. Transform is a complex property.

One might wonder then why I defined the syntax as $.animate({'rotate': '5deg'})? Well, ultimately I couldn't do $.animate({'transform': 'rotate(5deg)'}) because then rotation and scale couldn't be animated simultaneously or independently. jQuery does not allow for animating multiple-component CSS properties. jQuery only knows how to animate a single, simple numerical value for a CSS property. Something like this would not work: $.animate({'transform': 'rotate(5deg) scale(1)'})

Anyway... this is a long answer to your question, but may be useful to others.

Hi , I just want to say that you did an excellent job with this . I searched entire web to create a collage tool, but always got stuck at image rotation. Until i found your plug-in which is perfect . Thanks for your work. Awesome .

Trying to do a rotate, fade and scale in IE8 (and guessing earlier) results in just the fade working, and a Javascript error on Line: 62 Char: 9 of jquery-animate-css-rotate-scale.js saying 'undefined' is noll or not an object :-(

love to have some help here - see the referenced site. this works on all platforms for Safari 5+, FF 3.5+ and (more or less) Opera 10+
BUT, the whole script breaks in IE8 (I block less than 8). The IE debugger supplies this error:
'undefined' is null or not an object and pints to line 62 of this script.

Is there a patch I can apply, like if IE, get out?

I already test for the browser and version and store in an object within the "page" element (using data()).

love your work and really need to see what I can do here - I use the scale and rotate all over, mostly because of FF

To me it is ok that IS NOT WORKING on IE8 and below, better make an effort to make it work for IE9. IE8 anyway hold rotations only for multiple of 90 degree, which it is worthless for doing anything really interesting. I would say look forward for css3 and stop to look backward. Bad browser should be abandon - http://www.flickr.com/photos/littlemad/5209293150/

Interesting note: when you set the rotation of the div in your css, in my case to -120deg, when the rotation is called, it makes the div reappear (disappear then reappear) at 0deg, and then the animation proceeds and animates through the set +=120deg, as if it's position had been 0deg all along.

Thanks for the great plugin, but i found a little bug: If you rotate to a negative angle (i.e counter-clock wise) and then rotate back, the content is usually rotates on the shortest possible way (clockwise). In opera, however, it rotates the other way around (counter-clock wise) causing the content to flip over. This looks really funky depending on the context.

Line 130: m is null
I see that this patch to animate() was done with a purpose, and while it isn't causing any performance issues, I certainly hate seeing that little red "X" in my error console. Has anyone else experienced this null value?