Bonjour,

voici mon menu style "LavaLamp" ou "Fancy Menu" uniquement en JS sans librairie.

suite à la recommandation de kimjoa, il y a deux fichiers: un "compacté" et un "commenté" avec des variables plus explicites.

"compacté":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/** LavaLamp/Fancy menu : http://ftp-developpez.com/vodiem/source/js/LavaLamp , Date: 17/11/2009, Auteur: Vo Jacques */
var LLMenu = {
	menu:[],
	Wrap : function(id,sl,pos){
		var im=document.getElementById(id);
		cm=this.menu[id]={i:0,ni:35,t:20,is:im.getElementsByTagName("a"),sr:document.getElementById(sl),sd:pos};
		es=this.menu[id].is;
		im.onmouseout=Function("LLMenu.MoveTo('"+id+"','sd')");
		for(i=0;i<es.length;i++){
			es[i].onmouseover=function(id,i){return function(){LLMenu.MoveTo(id,i)}}(id,i);
			es[i].onclick=function(id,i){return function(){LLMenu.Clicked(id,i)}}(id,i);
			if(i==pos){cm.sr.style.top=im.offsetTop+Math.floor((im.offsetHeight-cm.sr.offsetHeight)/2)+'px';cm.sr.style.left=es[i].parentNode.offsetLeft+'px';cm.sr.style.width=es[i].offsetWidth+'px'};
		};
	},
	Clicked: function(m,pos){this.menu[m].sd=pos},
	MoveTo: function(m,pos){
		cm=this.menu[m];cm.i=0;e=cm.is[(pos=='sd')?cm.sd:pos];cm.ps=cm.sr.offsetLeft;cm.d=e.offsetParent.offsetLeft-cm.ps;cm.w=cm.sr.offsetWidth;
		clearTimeout(cm.timer);LLMenu.MoveToStep(cm,e);
	},
	MoveToStep: function(cm,e){
		cm.i++;x=(cm.i/cm.ni);p=Math.exp(-Math.pow(Math.pow((x-0.98)*1.7,2)-0.308,2)+0.095);d=cm.ps+p*cm.d;
		cm.sr.style.left=d+'px';cm.sr.style.width=(cm.w+(e.offsetWidth-cm.w)*p)+'px';
		cm.i%=cm.ni;
		if(cm.i!=0){cm.timer=setTimeout(function(){LLMenu.MoveToStep(cm,e)},cm.t)}
			else {cm.ps=e.offsetParent.offsetLeft;cm.sr.style.left=cm.ps+'px';cm.sr.style.width=e.offsetWidth};
	}
	};
"commenté":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
 * LavaLamp / Fancy Menu
 * http://ftp-developpez.com/vodiem/source/js/LavaLamp/
 *
 * Date: 17/11/2009
 * Auteur: Vo Jacques
 */
var LLMenu = {
	menu:[],
	Wrap : function(id,select,pos){
		var idMenu=document.getElementById(id);
		currentMenu=this.menu[id]={
			i:0,											//position dans l'animation
			ni:35,											//nombre d'animation
			t:20,											//delai entre deux animation en milliseconde
			items:idMenu.getElementsByTagName("a"),
			selecteur:document.getElementById(select),
			selected:pos
			};
		elements=this.menu[id].items;
		idMenu.onmouseout=Function("LLMenu.MoveTo('"+id+"','selected')");
		for(i=0;i<elements.length;i++){
			elements[i].onmouseover=function(id,i){return function(){LLMenu.MoveTo(id,i)}}(id,i);
			elements[i].onclick=function(id,i){return function(){LLMenu.Clicked(id,i)}}(id,i);
			if(i==pos){
				currentMenu.selecteur.style.top=idMenu.offsetTop+Math.floor((idMenu.offsetHeight-currentMenu.selecteur.offsetHeight)/2)+'px';
				currentMenu.selecteur.style.left=elements[i].parentNode.offsetLeft+'px';
				currentMenu.selecteur.style.width=elements[i].offsetWidth+'px';
				};
		};
	},
	Clicked: function(menu,pos){this.menu[menu].selected=pos},
	MoveTo: function(menu,pos){
		currentMenu=this.menu[menu];
		currentMenu.i=0;
		element=currentMenu.items[(pos=='selected')?currentMenu.selected:pos];
		currentMenu.posStart=currentMenu.selecteur.offsetLeft;
		currentMenu.distance=element.offsetParent.offsetLeft-currentMenu.posStart;
		currentMenu.widthStart=currentMenu.selecteur.offsetWidth;
		clearTimeout(currentMenu.timer);LLMenu.MoveToStep(currentMenu,element);
	},
	MoveToStep: function(currentMenu,element){
		currentMenu.i++;
		x=(currentMenu.i/currentMenu.ni);								//pourcentage d'avancement
		p=Math.exp(-Math.pow(Math.pow((x-0.98)*1.7,2)-0.308,2)+0.095);	//fonction unitaire de déplacement
		d=currentMenu.posStart+p*currentMenu.distance;					//position réel de déplacement
		currentMenu.selecteur.style.left=d+'px';
		currentMenu.selecteur.style.width=(currentMenu.widthStart+(element.offsetWidth-currentMenu.widthStart)*p)+'px';
		currentMenu.i%=currentMenu.ni;
		if(currentMenu.i!=0){currentMenu.timer=setTimeout(function(){LLMenu.MoveToStep(currentMenu,element)},currentMenu.t)}
			else {
			currentMenu.posStart=element.offsetParent.offsetLeft;
			currentMenu.selecteur.style.left=currentMenu.posStart+'px';
			currentMenu.selecteur.style.width=element.offsetWidth;
			};
	}
	};
pour son emploi, après déclaration, en fin de chargement:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
<script type="text/javascript">
	LLMenu.Wrap("menu","cursor",1);
</script>
avec:
"menu": l'id du menu
"cursor": l'id du curseur
1: la position de l'item du menu par défaut sélectionné (premier=0)

si vous avez plusieurs menu, vous pouvez jouer sur la vitesse en accédant aux propriétés (sinon tapez la valeur dans le code du script):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
LLMenu.menu["menu"].t=10;
t: delai entre deux animations en milliseconde
ni: nombre d'itération pour l'animation
soit ni*t = le temps total de l'animation

pour changer la courbe de déplacement il faut changer "la fonction unitaire de déplacement":
fonction définit pour l'intervalle 0 à 1 avec f(0)=0, f(1)=1 (de préférence car f(0) étant la position initiale, f(1) la position finale, seront multipliées par la distance).
après plusieurs essai de fonction sinusoïdale, polynomiale, c'est l'exponentielle que j'ai retenu. mais le plus important c'est qu'il faut avoir un extrémum à 0 et à 1 (soit dans l'idée: f'(0)=0, f'(1)=0) et éventuellement plusieurs entre les deux pour ne pas avoir de discontinuité qui provoquera des sauts du curseurs disgracieux.
sinon rien ne vous empêche de coder autrement cette partie.

autre sujet (et le seul que j'ai trouvé) uniquement en JS est celui de le_chomeur ici

testé sous FF3.5, IE7, Opera10,Chrome3

par ici pour la démo

merci de vos appréciations et commentaires.