IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

[SRC] LavaLamp / Fancy Menu Lite


Sujet :

Contribuez

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Par défaut [SRC] LavaLamp / Fancy Menu Lite
    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.


  2. #2
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    Salut ^^

    effectivement je m'étais penché sur le sujet il y a un moment déja ;-)

    j'aime bien ta version, clair net et simple ( on dit merci monsieur pener pour ses équations je m'en sert également partout ^^ )

    juste une chose qui me chagrine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    elements[i].onmouseover=Function("LLMenu.MoveTo('"+id+"',"+i+")");
    elements[i].onclick=Function("LLMenu.Clicked('"+id+"',"+i+")");
    pourquoi ne pas utiliser une closure plutôt :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var u=function(id,i){
    <div style="margin-left:40px">return function(){
    LLMenu.Clicked(id,i);
    }</div>}(id,i);
     
    elements[i].onmouseover = u ;
    voila ;-)

  3. #3
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Par défaut
    salut le_chomeur ,

    merci pour ton appréciation d'autant qu'au vu de tes contributions tu me semble assez éclairé et que j'apprécie aussi ta rédaction assez clair.

    pour les équations sur lesquels j'ai travaillé, c'est du fait maison avec l'aide du grapheur en ligne ici et d'un tableur. le tableur m'a servi à un moment donné pour trouver la fonction de conversion pour avoir un débordement régulier qq soit la distance.
    comme tu peux le voir avec ces tests:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		/* autre fonction sinusoidale
    		h=(Math.sqrt(h-0.995)-0.07)*1.03;									//fonction empirique de conversion h en coef pour la fonction de déplacement. Convenable pour h de 1 à 1,3
    		p=h*Math.sin(Math.PI*x)+Math.sin(Math.PI*0.5*x);					//fonction unitaire de déplacement
    		*/
    		/* autre fonction polynomiale
    		a=-1/Math.pow(80*h-78.05,2)+2.963*h-2.7;										//fonction empirique de conversion h en coef pour la fonction de déplacement. Convenable pour h de 1 à 2
    		p=a*(4*Math.pow(x,3)-9*Math.pow(x,2)-2*Math.sqrt(x)+7*x)+(2*Math.sqrt(x)-x);	//fonction unitaire de déplacement
    		*/
    je n'ai pas fait cette conversion pour cette fonction exponentielle qui ne fait pas partie de la liste de penner.
    j'utilise l'exponentielle d'une fonction polynomiale du 4ème degré alors que dans ses exemples il utile du 2ème degré qui ne me paraissait pas assez satisfaisant.

    je ne connaissais pas la rédaction de penner et je te remercie de cette découverte qui donne de bonne base.
    (je ne me lasse pas de me rincer l'oeil sur de belles courbes... ^^)

    Citation Envoyé par le_chomeur
    juste une chose qui me chagrine
    ha? toi aussi ca te chagrine? lol
    s'il y a avait que ca qui me chagrinait...
    Citation Envoyé par le_chomeur
    pourquoi ne pas utiliser une closure plutôt...
    he bien parce que j'attendais que tu me donnes le code.

    je ne parvenais pas à trouver la bonne syntaxe: j'obtenais que la dernière valeur i de la boucle et pas celui relatif au menu.
    je ne te cache pas que je trouvais cela très contraignant: je ne pouvais pas faire passer d'objet dans la fonction.

    je n'ai pas encore ton expérience en js.
    je suis encore un bleu en ce domaine: pour preuve j'ai fait des recherches sur ce que voulais dire la syntaxe "<blockquote>" dans ton code. lol

    merci pour tes remarques, je ferais les modifications ultérieurement.

  4. #4
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    justement je l'ai donné la solution en version closuré


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var u=function(id,i){return function(){
    LLMenu.Clicked(id,i);
    }}(id,i);
     
    //Passage de l'id et de i COURANT et non le dernier
    //Renvoyant une fonction avec les paramètres "en dur" ;-) 
     
    elements[i].onmouseover = u ;

  5. #5
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Par défaut
    je te remercie, j'avais effectivement compris et vérifié que cela fonctionnait bien.

    edit 19/11/09: Voilà, le code est maj.

Discussions similaires

  1. [JavaScript] [SRC] DropDown Menu Lite
    Par vodiem dans le forum Contribuez
    Réponses: 8
    Dernier message: 13/11/2009, 20h11
  2. [JavaScript] [SRC] MBox ( un lightbox lite ( diaporama d'image) )
    Par le_chomeur dans le forum Contribuez
    Réponses: 14
    Dernier message: 24/06/2009, 21h07
  3. souci avec le fancy menu
    Par eilijah dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 16/09/2008, 09h46
  4. [MooTools] "Fancy Menu" avec Mootools
    Par Manatee dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 18/04/2008, 09h10
  5. [JavaScript] [SRC] menu déroulant horizontal
    Par Auteur dans le forum Contribuez
    Réponses: 1
    Dernier message: 08/06/2007, 23h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo