2 exemples de navigation suivant la souris avec jQuery

Je continue de partager avec vous les choses qui me passent par la tête et que je me débrouille (tant bien que mal) à réaliser.
Vous vous souvenez de ces navigations flash qui suivaient la souris et qui se déployaient autour du curseur ? Amusons-nous avec notre bibliothèque javascript préférée.

Il y a de nombreuses façons d’appliquer ce concept de menu mobile, je vous propose 2 possibilités.

La première étant un bloc glissant sur le côté et suivant les mouvements de la souris seulement dans l’axe verticale, et un menu qui se déploie sur toute la longueur de la colonne de contenu.

La démo 1

Voici la structure HTML du menu uniquement


Le menu étant le bloc qui va contenir toute la navigation. On place les boutons dans une liste qu’on camoufle et qui s’ouvrira quand on cliquera sur le ’bouton opener’.

Voici le CSS :

#container {
	position:relative;
	width:800px;
	margin:0 auto;
	padding:50px 20px;
	height:1200px;
	background:#fefefe;
	border:1px solid #eee;
	border-top:none;
	border-bottom:none;
}
#menu {
	position:absolute;
	display:block;
	padding:0;
	color:#fff;
	left:0;
	top:0;
	width:840px;
	height:40px;
}
.opener {
	cursor:pointer;
	position:absolute;
	float:left;
	width:120px;
	background:#555;
	text-align:center;
	padding:10px 0;
	color:#fff;
	left:-110px;
	border-right:1px solid #ddd;
	-webkit-border-radius:4px 0 0 4px;
	-moz-border-radius:4px 0 0 4px;
	/*border-radius:4px 0 0 4px;*/
}
.opener:hover,
.opener:focus,
.opened {
	background:#eee;
	color:#474747;
}
#menu ul {
	margin:0;
	height:38px;
	width:840px;
	background:#eee;
}
#menu li {
	float:left;
	list-style:none;
	border-right:1px solid #ddd;
	padding:0;
}
#menu li a {
	float:left;
	padding:10px 20px 9px 20px;
	background:#eee;
}
#menu li a:hover {
	background:#eee;
}

Et sans plus de détails, voici le javascript :

$(document).mousemove(function(e){
	$(".close").stop(true,false).animate({top : (e.pageY - 15)},500)
});
$("#menu ul").hide();
$("#menu span").click(function(){
	$(this).removeClass('close');
	$("#menu ul").slideDown();
	$("#menu .opener").addClass('opened');
});
$("#menu").mouseleave(function(){
	$(this).addClass('close');
	$("#menu ul").slideUp();
	$("#menu .opener").removeClass('opened');
});

Ce qui est essentiel ici, c’est la petite fonction qui passe presque inaperçu ‘.pageY’ qui va nous renvoyer la position de notre souris (verticalement). Et grâce au ‘animate’, nous allons donner l’impression que le bloc suit la souris, n’oubliez pas le ’stop(true,false)’ pour la fonction se recharge au moindre déplacement.

Et voici le deuxième menu qu’on faisait il n’y a pas si longtemps que ça entièrement en flash, mais c’est beaucoup de contraintes, et javascript c’est quand même bien plus marrant, non ? :p

Voici la démo 2

Et la structure HTML du menu :


Et le CSS associé :

#container {
	position:relative;
	width:800px;
	margin:0 auto;
	padding:50px 20px;
	height:1200px;
	background:#fefefe;
	border:1px solid #eee;
	border-top:none;
	border-bottom:none;
}
#menu {
	position:absolute;
	width:100px;
	height:100px;
}
#menu a {
	float:left;
	width:32px;
	height:32px;
	position:absolute;
	display:none;
}
#menu a.home {
	background:url(../images/Home.png) no-repeat;
	top:80px;
	left:34px;
}
#menu a.about {
	background:url(../images/User.png) no-repeat;
	top:-20px;
	left:34px;
}
#menu a.folio {
	background:url(../images/Pictures.png) no-repeat;
	top:10px;
	left:75px;
}
#menu a.contact {
	background:url(../images/Chat.png) no-repeat;
	top:60px;
	left:75px;
}
#menu a.rss {
	background:url(../images/RSS.png) no-repeat;
	top:60px;
	left:-10px;
}
#menu a.links {
	background:url(../images/Address_Book.png) no-repeat;
	top:10px;
	left:-10px;
}
#menu a span {
	display:none;
	position:absolute;
	padding:3px 5px;
	-webkit-border-radius:4px;
	-moz-border-radius:4px;
	/*border-radius:4px;*/
	background:#666;
	color:#fff;
	top:-30px;
	z-index:9;
}
.note {
	background:#666;
	color:#fff;
	display:block;
	padding:5px;
	-webkit-border-radius:4px;
	-moz-border-radius:4px;
	/*border-radius:4px;*/
	width:110px;
}

Ici j’ai placé les images en absolue et j’ai indiqué leur position en top et left, mais j’aurais pu m’en passer puisque les icônes sont cachées et se positionnent grâce au javascript quand elles apparaissent.

Et le petit javascript qui va avec :

var winWidth = $(window).width();
	var contWidth = $("#container").width();
	var decalage = ((winWidth - contWidth) / 2);

	jQuery.fn.follow = function(){
		$(document).mousemove(function(e){
			$(".close").css({top : (e.pageY - 50), left : ((e.pageX - decalage)-30)});
		});
	};

	const mobil = 0;
	const arret = 1;
	var deplac = mobil;

	$("#menu").addClass('close').follow();

	$(window).keydown(function(event) {
		var arc_paramsHome = {
	    	center: [34,30],
	        radius: 50,
	        start: 0,
	        end: 1,
	        dir: -1
		}
		var arc_paramsAbout = {
	    	center: [34,30],
	        radius: 50,
	        start: 180,
	        end: 181,
	        dir: -1
		}
		var arc_paramsFolio = {
	    	center: [34,30],
	        radius: 50,
	        start: 120,
	        end: 121,
	        dir: -1
		}
		var arc_paramsContact = {
	    	center: [34,30],
	        radius: 50,
	        start: 60,
	        end: 61,
	        dir: -1
		}
		var arc_paramsRss = {
	    	center: [34,30],
	        radius: 50,
	        start: 300,
	        end: 301,
	        dir: -1
		}
		var arc_paramsLinks = {
	    	center: [34,30],
	        radius: 50,
	        start: 240,
	        end: 241,
	        dir: -1
		}

		$("#menu a").hover(function(){
			$(this).find("span").fadeIn();
		},function(){
			$(this).find("span").stop(true,true).fadeOut();
		});

		if (event.keyCode == '38') {
			if (deplac == mobil) {
				deplac = arret;
				$("#menu").removeClass('close');
				$("#bloc a").fadeIn(50);
				$("#menu .note").fadeOut();
				$("#menu a.home").animate({path : new $.path.arc(arc_paramsHome)},500);
				$("#menu a.about").animate({path : new $.path.arc(arc_paramsAbout)},500);
				$("#menu a.folio").animate({path : new $.path.arc(arc_paramsFolio)},500);
				$("#menu a.contact").animate({path : new $.path.arc(arc_paramsContact)},500);
				$("#menu a.rss").animate({path : new $.path.arc(arc_paramsRss)},500);
				$("#menu a.links").animate({path : new $.path.arc(arc_paramsLinks)},500);
			};
		};
	});
	$(window).keyup(function(event) {
		deplac = mobil;
		$("#bloc a").fadeOut(function(){
			$("#menu .note").fadeIn();
		});
		$("#menu").addClass('close');
	});

Comme ça il a l’air grand, mais c’est que je n’ai pas trouvé le moyen de réduire les variables de rotations.

On utilise les fameux .pageX et .pageY pour récupérer la position de la souris et on positionne le menu grâce à un ‘.css()’ qui nous repositionne la div en direct.

Alors le gros défaut de cette version pour le moment c’est qu’on ne peut pas cliquer sur les liens de la page même ou sélectionner un texte à cause de la div ‘note’ que j’ai mise pour indiquer quelle touche enfoncer. Mais il y a possibilité d’éviter ça, il suffit de ne pas mettre de note et d’indiquer la façon de procéder autrement.

J’espère que cet article vous inspirera, amusez-vous bien.

4 réponses à “2 exemples de navigation suivant la souris avec jQuery”

  1. 1
    sebastien dit :

    Très sympa, tes articles sont vraiment interessants. Dans la vie, tu exerces en tant que freelance ?

    • 1.1
      admin dit :

      Merci beaucoup, je m’efforce au mieux de rendre ces articles ludiques et compréhensibles, même s’ils ne sont pas parfaits. ^^
      Je ne suis pas en freelance, je crée des sites web dans une petite agence de com. Mais je consacre beaucoup de temps libre à cette passion pour ce qui touche au webdesign, toujours dans le but de m’améliorer.

      Bonne continuation, et à bientôt. :)

  2. 2

    Hope it’s okay if I comment here in English…

    Before I say anything else, I just wanted to say that this is great work, congratulations!

    Now…

    Wouldn’t be easier if the menu trigger function was bound to the middle mouse button?

    api.jquery.com says you can’t detect the right mouse button reliably on Opera and Safari but it doesn’t says anything about the middle one specifically.

    Demo 2 isn’t working on Chrome 5 too. Just thought I’d let you know…

    Keep up the great work!

    • 2.1
      admin dit :

      Thanks very much !
      I completly agree with you, the trigger is not the good one, but I couldn’t find a good one, you’re idea sounds great, I will search if it’s possible.
      I make my demonstrations only with firefox, not because I am against the others browsers, but I don’t take time to check them… I know It’s not a good practice, but It’s so boring to see that something working here, don’t somewhere else… :p
      Anyway, thanks again. :)