/    Sign up×
Community /Pin to ProfileBookmark

Animated Image Rollovers

Hi everybody.

I’m trying to make a script, which would start an animation of an image link, when you mouseOver it and do the same in reverse, when you mouseOut. Something like here: [URL=”http://www.alistapart.com/articles/sprites2″]http://www.alistapart.com/articles/sprites2[/URL], but without jQuery or stuff like that.

It should use separated images, not animated GIFs.

I also found this: [URL=”http://www.javascript-fx.com/ani_rollovers/demo2.html”]http://www.javascript-fx.com/ani_rollovers/demo2.html[/URL], but their [URL=”http://www.javascript-fx.com/ani_rollovers/javascript/JSFX_AnimatedRollovers.js”]script[/URL] was just too hard to understand for me.

Gil Davis has this on his website: [URL=”http://gil.davis.home.att.net/rotate2.htm”]http://gil.davis.home.att.net/rotate2.htm[/URL], but this only works for 1 image. I guess I would need separate functions and variables for each image link, which doesn’t seem to be exactly a KISS solution.

I tried to make something by myself:

[CODE]
function mouseAction(up,imgName,fileName,max)
{
function animUp()
{
if (parseInt(source.substr(source.lastIndexOf(“.”)-1,1))!=max)
{
source=(fileName+(parseInt(source.substr(source.lastIndexOf(“.”)-1,1))+1)+”.png”);
} else
{
clearInterval(intervalId);
running=false;
}
}
function animDown()
{
if (parseInt(source.substr(source.lastIndexOf(“.”)-1,1))!=0)
{
source=(fileName+(parseInt(source.substr(source.lastIndexOf(“.”)-1,1))-1)+”.png”);
}
}
function waitForStop()
{
if (running) setTimeout(waitForStop(),100)
else intervalId=setInterval(“animDown()”,interval);
}
var interval=500;
var intervalId=0;
var running=false;
var source=window.document.images[imgName].src;
if (up)
{
running=true;
if (intervalId!=0) clearInterval(intervalId);
intervalId=setInterval(“animUp()”,interval);
} else waitForStop();
}[/CODE]

In my code, all images should have their sequential number as the last character before “.png” starting from [B]0[/B] and ending with [B]max[/B]. It was called in the body as:

[code=html]<a href=”#” onmouseover=”javascript: mouseAction(true,’foo1′,’bar1_’,4)” onmouseout=”javascript: mouseAction(false,’foo1′,’bar1_’,4)”><img name=”foo1″ src=”bar1_0.png” /></a>[/code]

However, this doesn’t work, because when the [B]mouseAction()[/B] function ends, [B]setInterval()[/B] can’t find the nested functions.

Does anybody know about a script that does what I need? Or do you have any suggestions to the posted scripts? Thanks for any advice.

to post a comment
JavaScript

3 Comments(s)

Copy linkTweet thisAlerts:
@bluestartechMar 07.2009 — there is surely a solution available using jquery or scriptacolous, why invent the wheel?
Copy linkTweet thisAlerts:
@haulinauthorMar 07.2009 — Because. I am only learning Javascript now and I don't want to jump into something, that does all the work for me. I want to know [U]how[/U] stuff works. I am trying to work this out for a few days now and i keep getting stuck on small problems, so I thought somebody more experienced could maybe help me with this. I will keep on googling. Maybe an object-based solution could solve my problems...
Copy linkTweet thisAlerts:
@haulinauthorMar 15.2009 — Just in case anybody would need it:

With an idea from hesido, I managed to write that script:

[CODE]
function anim(elem,arr)
{
if (elem.intervalId) window.clearInterval(elem.intervalId);
elem.intervalId=window.setInterval(function()
{
var i=0;
while (elem.className!=arr[i]) i+=1;
if (i<arr.length-1) elem.className=arr[i+1];
else window.clearInterval(elem.intervalId);
},interval);
}

function initAnims()
{
function animUp()
{
var animClasses=["anim_l0","anim_l1","anim_l2"];
anim(this,animClasses);
}
function animDown()
{
var animClasses=["anim_l2","_anim_l1","anim_l0"];
anim(this,animClasses);
}
var animEl=window.document.getElementById("menu").getElementsByTagName("a"), i;
for(i=0; i<animEl.length; i+=1)
{
animEl[i].onmouseover=animUp;
animEl[i].onmouseout=animDown;
}
}

var interval=50;
if (window.document.getElementById && window.document.getElementsByTagName)
{
if (window.addEventListener) window.addEventListener('load',initAnims,false);
else if (window.attachEvent) window.attachEvent('onload',initAnims);
}
[/CODE]


HTML goes like this:
[code=html]
<div id="menu">
<ul>
<li><a href="#" class="anim_l0"><span>Menu Item</span></a></li>
</ul>
</div>[/code]


CSS:
[CODE]
#menu ul li a {background-image: url(foo.png);}
#menu ul li a.anim_l0 {background-position: 0px 0px;}
#menu ul li a.anim_l1 {background-position: 0px -103px;}
#menu ul li a.anim_l2 {background-position: 0px -206px;}
[/CODE]


where [B]foo.png[/B] is a 3-state pic of the animated element; each state is 103px high.

P.S.: I also found out why [B]setInterval()[/B] couldn't find the nested functions in my first post. You need to pass it a function identifier instead of a string to be executed. Then the [B]setInterval()[/B] has still acces to stuff of the outer function. So [I]intervalId=setInterval("animUp()",interval);[/I] should be [I]intervalId=setInterval(animUp,interval);[/I], however I didn't use this in my solution.
×

Success!

Help @haulin spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...