Thursday, September 6, 2012

Rotating DOM Elements with CSS and jQuery

I've been doing some research for a project I'm working on that requires an option to rotate elements in various ways. I already knew that rotation in a browser is fairly new and has various levels of support in each browser. I was also aware of the CSS3 transform style.

So I started by just looking at the CSS aspect to see what was possible knowing that I could plug whatever I found into jQuery's css method.

At samuli.hakoniemi.net I found this basic demonstration of the different browser specific methods:


-moz-transform:rotate(45deg);
-webkit-transform:rotate(45deg);
-o-transform:rotate(45deg);
-ms-transform:rotate(45deg);


You can see the demo here.

At www.the-art-of-web.com we can go a little further and even apply animations:


#submenu {
background-color: #eee;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
-ms-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}

#submenu:hover {
background-color: #fc3;
-webkit-transform: rotate(360deg) scale(2);
-moz-transform: rotate(360deg) scale(2);
-o-transform: rotate(360deg) scale(2);
-ms-transform: rotate(360deg) scale(2);
transform: rotate(360deg) scale(2);
}


I'm using the latest Firefox release and all the examples worked as expected. This is pretty exciting that you can actually apply complex motion only with CSS.

However, I know I will still need some additional control and will not just want a predefined transition. Since I am using jQuery, I wanted to see what was available to achieve dynamic rotational transforms and animations.

I thought jQuery might have something in place to do this already, but you pretty much have to coordinate animate() and css() together through the step callback:


$('#myDiv').animate({ left: 50, top: 50 }, {
step: function(now, fx) {
$(this).css('transform','rotate('+(fx.pos * 90)+'deg)');
},
duration: 2000,
easing: 'easeInQuint'
});


Try out the jsFiddle to see it work.

The nice thing jQuery does here, is normalize the CSS3 transform style and translate it into the browser specific notation. So you don't have to add all the possible variations in each time you use it. However, the animate() method does not natively support animating the transform style so you have to use the step callback to achieve that part of the animation.

The above approach seems doable but I was wondering what other choices might exist to make it easier to animate transforms like rotations. So I did a quick search and found three possible alternatives:



  • zachstronaut.com - A jQuery patch to add rotation and scale plugins and animations. It exclusively uses the CSS3 transform attribute so will only be functional in relatively new browsers. Very little code to make it happen so there's no giant footprint added to get this functionality.



  • jquery.transit - An alternative to jQuery css and animate. You use the transition plugin to do all your animation. The augmented css() method provides more expressive ways to apply transforms. The animate method understands how to animate tranform styles. This seemed a little more than I needed but appears to be a fairly powerful plugin.


  • jqueryrotate - This supports older browsers but can only rotate images.



With this knowledge, I think some prototyping is needed to see if any of these libraries will benefit what I'm building.