Cool Flash Effect Without Flash

I promise this is something you haven’t seen with Mootools yet, maybe not even JavaScript. My goal was to emulate an effect that you can see over at alician blue. Notice how the blue slides in when you hover over the navigation links. That’s pretty simple, right? Mimicking with Mootools was actually pretty simple too.
First we start off with a standard navigation list:
<ul id="nav"> <li><a href="#">These aren't images!</a></li> <li><a href="#">And they aren't made with flash!</a></li> <li><a href="#">It's all dynamic javascript!</a></li> </ul>
Here’s the CSS:
#nav { margin:1em; list-style:none; } #nav a { font-size:24px; font-weight:bold; color:#f60; text-decoration:none; } #nav a span.hover { color:#06f; position:absolute; cursor:pointer; }
Rather than styling the :hover state of the link, we style a span class, ‘hover’ in this case. It needs to be absolutely positioned because it’s going to be placed on top of the original link. We’ll also set the cursor to pointer for good measure.
Now we have two choices: (1) Just wrap the span in a div and adjust the width of that, or (2) use the clip property. At first, I chose number one, but the effect only slides from left to right, which would achieve the desired result, but why stop there when I can do more? So two it is. Using the clip property will allow us to start the slide from the middle outwards. But there’s a problem. Mootools effects don’t support the clip syntax which looks something like this: clip: rect(20, 100, 100, 20). For more info on using the clip property, try this thumbnail tutorial. Luckily, while searching the Mootools forums, I came across Fx.CSS.Clip. Here’s how I implemented it:
Fx.CSS.select = function(property, to){ if (property.test(/color/i)) return this.Color; if (property.test(/^clip$/i)) return this.Clip; // this is the line that needs to be added var type = $type(to); if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi; return this.Single; }; Fx.CSS.Clip = { parse: function(value){ if (value.push) return value; var res = value.match(/rect\((\d+)px[,]?[ ]+(\d+)px[,]?[ ]+(\d+)px[,]?[ ]+(\d+)px\)/i|>); if (!res) return [0,100,100,0]; // Anything to give the developer feedback something's wrong return [parseInt(res[1]), parseInt(res[2]), parseInt(res[3]), parseInt(res[4])]; }, getNow: function(from, to, fx){ var now = []; for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i])); return now; }, getValue: function(value){ var ret = []; for (var i=0; i<value.length; i++) { if (i > 0) ret += " "; ret += value[i] + "px"; } return 'rect(' + ret + ')'; } };
In order for this to work, the creator actually modified the Mootools function Fx.CSS.select. I simply overwrote it in this case because I’d rather not hack the library. Now that we can animate the clip propterty, let’s get started.
window.addEvent('load', function () { $$('#nav a').each( function (el) { var height = el.offsetHeight; var width = el.offsetWidth; var mid = Math.round(width / 2) var hover = new Element('span', { 'class':'hover', 'styles': { 'top': el.getTop(), 'left': el.getLeft(), 'clip': 'rect(0px '+ mid +'px '+ height +'px '+ mid +'px)' } }).setText(el.getText()).injectInside(el); var fx = hover.effect('clip', {'wait': false, 'duration':600, 'transition':Fx.Transitions.Quint.easeOut}); el.addEvents({ 'mouseover': function () { fx.start([0,width,height,0]); }, 'mouseout': function () { fx.start([0,mid,height,mid]); } }); }); });
Let’s get our links with a css selector and loop through each of them. Then we’ll save the values that we’ll be using a lot in some variables. Next we’ll create the overlay span, give it a class, set some styles to place it over the original link and hide it, set its text to the same as the link, and inject it inside the link. Easy peasy.
After that, we create an effect that will alter the clip property values of our overlay span. Almost done now. To start the effect, we just add mouseover and mousout events that adjust the clip appropriately. By changing the clip values, you could have the color slide in from any direction. See it in action below:

August 9th, 2007 at 3:43 pm
Wow, that looks impressive Chris. I’d have to say it looks better than the original site, as yours quits changing colors when you hover over it and reverts back. On the other site it completes the color transformation.
August 9th, 2007 at 4:23 pm
Yeah, their implementation is actually a little buggy, too. But I’ve seen the effect elsewhere. That’s just the only site I remembered off-hand.
August 17th, 2007 at 2:32 pm
Nice work, I do like this. Looks nice and runs well and has good compatibility.
December 20th, 2007 at 11:26 pm
Can this be implemented inside layers?
December 22nd, 2007 at 10:03 am
Steve: Sorry, I don’t understand your question.