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.
Very nice, and not overly dramatic to make it seem unnecessary. I could see this being implemented in a lot of really great ways.
hmm not working in Chrome 8.0.552.224 :( but looks nice in Safari
css3 awesome … in IEless world :)
Ya its not working on chrome 10.0.612.1
perfect on safari. gr8 tho!
Very interesting! Works good on Firefox, but like other people are saying, not working in IE7 or Chrome.
IE9 now supports CSS transform, is there any particluar reason that it wasn’t included? (other than who knows if it’ll actually make it into the final release)
What would be really interesting is to see this done without the ray.png. I’ve seen a sunburst type design done in the CSS3 iOS icons, it should be possible, I would think!
The Safari issue surprises me — I’ll look into that.
I don’t yet have an IE9-compatible OS so I couldn’t test — that’s why it wasn’t included.
Ahhh, in the switch statement of the Browser.name, there is no case for Chrome, only safari. ;-) Hence the reason chrome doesn’t spin.
It didn’t work in any browser for me! (Chrome 7, FF 3.6, FF 4, Opera) :-(
Tested IE, this works beautifully in the IE platform preview 7 (the only place ms-transform is supported thus far) works just fine with a case statement for IE, and a cssPrefix of “ms”.
Thanks for this, David. Love the effect. :-)
doesnt work in Chrome in ubuntu 10.10
But works in firefox.
Realy cool
I’ve updated the post for Chrome and IE!
Got it tested under Ubuntu Chrome and it’s really awesome!
I’ve seen something similar to this at:
http://scripty2.com/
G R O O v y !
Oh snap, I though you did it using MooTools!
The power of habit :P
It is using mootools. ;-)
@dustin
yea, I feel dumb.
Really beautiful. I love the effect. The code is not very complicated and I can understand. Thank you so much for sharing great article.
Great work David…
BTW. Web browsers still need some performance optimization. This simple effect use 50% of my CPU (MacBookPro C2D 2,4 GHz) :-/
Does not work in any browser for me either, I’m on a PC. I tried Chome, Firefox, Safari and Opera
I’m on windows 7 and it works fine in Chrome 8, Firefox 3.6, IE9 Platform Preview, and Safari 5
Very nice effect
Does it work only with moo1.3 or with older versions (1.2.5) too?
1.2.5 should work if you have the Browser object with it. The periodical code will work with any version of MooTools; the browser sniffing is what you’d need to make sure you had, or customized.
nice tut.
really smooth and nice work.
useless as it only targets specific rendering engines
Really? It works in Safari, Chrome, Firefox, IE9, and will soon work in Opera (if they keep their word), I don’t know what the hell else you would want?
No, it doesn’t work in Netscape Navigator 4.7.
Works nicely on my HTC Desire running Android 2.2
The code is slightly wrong in the sense that it doesn’t skip IE like the comments indicate. Setting the cssPrefix to false in the case of IE would actually be correct.
Considering IE9 supports CSS transforms, I believe it is correct. (You’ll have to check out the platform preview 4 to see this, and it will be in the final release of IE)
You can actually detect which transform property to use instead of that nasty browser sniff branch.
https://gist.github.com/523692
Very cool, I love it!
Is there a way to do that with jQuery as well?
I’m afraid that in win7(32bit) with FF 3.6.13 or Opera 11.00 1156 the script doesn’t work.
Any tip about that?
Thank you!
jQuery version?
what should i do in html page ?
no one know about my question ?
I’ve been looking at these kind of animations for a while and your solution is quite elegant. Thanks for the post.
I had a go at a no js version of this. I thought you might like to see a completely javascript free version.
I’ve been playing around with css3 animation. This is the Safari webkit code, but it can be made to work in FF etc.
in the #rays
and the animation style
This is a top effect.. I will be implementing this effect for my little poster website next week.(www.zip-posters.co.uk)
It Works great on Mac Chrome, Safari, FF, Opera etc
Works on FF,Safari & Chrome… But the rotation in chrome is a bit choppy and had to do a work around in IE to make it static and also not working on IE 9 Beta. but at least it displays
Shame about IE, but then again it’s a shame about IE…
I think IE was invented purely as a mechanism for stressing web devs out and making them work for there money.
…Love this Site David
Great stuff mate, love it!
I just stole your demo’s rays-main.png image: http://www.cmsbox.com/de/cms
I went for CSS Animations though.
Love the effect. I’ll also be using this – Thanks man!
This effect could be done in pure CSS with animations by keyframes. Just a thought… :)
It’s indeed fun and educational to see how this is done.
In real life though, I am wonder if you can use this to make text blink or scroll left or right, up or down.