Create Spinning Rays with CSS3 Animations & JavaScript

Thomas Fuchs, creator of script2 (scriptaculous' second iteration) and Zepto.js (mobile JavaScript framework), creates outstanding animated elements with JavaScript. He's a legend in his own right, and for good reason: his work has helped to inspire developers everywhere to drop Flash and opt for JavaScript development for smooth UI's. One simple effect I enjoy is the script2 website's rotation of a ray image. Let me show you how Thomas did it!

The CSS

There's very little CSS to add to your stylesheet:

#rays { background:url(rays.png) 0 0 no-repeat; position:absolute; top:0; left:0; width:490px; height:490px; transform:scale(1) rotate(16.768rad); }

The rays image should be a background image and it's probably best to set the element's dimensions. You can set an initial rotation value as well.

The JavaScript

The spinning rays effect works by using JavaScript to update browser-specific CSS3 animation properties. The first step is detecting the browser:

var cssPrefix = false; switch(Browser.name) { case "safari": cssPrefix = "webkit"; break; case "chrome": cssPrefix = "webkit"; break; case "firefox": cssPrefix = "moz"; break; case "opera": cssPrefix = "o"; break; case "ie": cssPrefix = "ms"; break; }

I've chosen to use MooTools' Browser object to detect the browser. jQuery and other libraries provide a method by which to get the current browser. As you can tell by the code, this effect will support Webkit-based browsers (Chrome, Safari, Webkit-mobile), Firefox, and Opera. Once the current browser is detected, you set forth a setInterval directive to perodically update the degree rotation of the element:

// Spin them rays! if(cssPrefix) { // Skip IE! var rays = document.getElementById("rays"), degrees = 0, speed = 0.05; setInterval(function() { degrees += speed; // degree adjustment each interval rays.setAttribute("style","-" + cssPrefix + "-transform:rotate(" + degrees + "deg)"); },20); }

With MooTools it would look like:

// Spin them rays! if(cssPrefix) { // Skip IE! var rays = $("rays"), degrees = 0, speed = 0.05; (function() { degrees += speed; // degree adjustment each interval rays.set("style","-" + cssPrefix + "-transform:rotate(" + degrees + "deg)"); }).periodical(20); }

I've found a 20 millisecond class assignment interval provides a smooth but subtle transition. After all you don't want the ray movement to steal the user's attention. To add some fun you could adjust the speed of the animation when the user mouses in and out of the element:

rays.addEvents({ mouseenter: function() { // 5x! Warp speed! speed = 0.25; }, mouseleave: function() { // Back to normal; speed = 0.05; } });

Subtlety is the key to using this effect...effectively. Using CSS properties to transition the element's rotation is even more optimal, seeing as they're native to the browser. You'll want to be sure not to use this effect to much on a given page, as many concurrent animations can be taxing to any browser. I'd also like to point out that Safari and Chrome handle these animations best.