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é":
"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 /** 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}; } };
pour son emploi, après déclaration, en fin de chargement:
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; }; } };
avec:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 <script type="text/javascript"> LLMenu.Wrap("menu","cursor",1); </script>
"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):
t: delai entre deux animations en milliseconde
Code : Sélectionner tout - Visualiser dans une fenêtre à part LLMenu.menu["menu"].t=10;
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.
![]()
Partager