Créer une horloge polaire avec JS et Canvas

22 juin 20102 commentairesTutoriels , , ,

Amorcés avec html4 puis officialisés avec l’avènement de html5, les Canvas font partie des apports les plus importants des standards modernes.

Aujourd’hui, je vous propose un tutoriel Javascript pour réaliser une horloge polaire.

Une horloge po… Quoi?

L’horloge polaire représente une date et une heure grâce à une série de cercles concentriques.

Je me suis énormément inspiré de l’économiseur d’écran proposé sur le blog de pixel breaker et disponible ici.

Retrouvez ici le résultat final. Utilisateurs d’Internet explorer s’abstenir, les Canvas ne sont correctement interprètes que par des navigateurs récents (chrome, Firefox, safari, …). Cependant dans d’autres cas, il est possible d’employer des Javascript pour contourner le problème.

Principe

Pour réaliser notre horloge nous allons superposer un ensemble de disques, du plus large pour l’heure au plus petit pour les dixièmes de seconde.

HTML

Pour commencer voici notre base HTML :

<h1>Horloge polaire</h1>
 
<canvas id="chrono" width="200" height="200"></canvas>
 
<div id="clock"></div>

Le div #clock recevra la date au format texte via une instruction javascript.

CSS

Ajoutons de la couleur à l’ensemble!

body{
	text-align:center;
	font-family:Arial, Helvetica;
}
canvas{
	padding:20px;
}
h1,#hour{color:#97BF4F;}
#minute{color:#999;}
#second{color:#666;}
#millisecond{color:#333;}

Javascript

Attaquons maintenant le javascript. Rappelez-vous, nous allions superposer un ensemble de disques concentriques. Pour ça, nous allons utiliser la méthode arc(). Cette fonction utilise la notation suivante :

//on définit le contexte "2D" de notre canvas
var canvas = document.getElementById("mon_canvas");
var ctx = canvas.getContext("2d");
 
//on commence le tracé
ctx.beginPath();
ctx.arc(x,y,r,angleDeDepart,angleDArrivee,sensInverse);
ctx.fill();

x,y type:Nombre sont respectivement l’espacement vertical et horizontal en partant du coin supérieur gauche.
r type:Nombreest le rayon du cercle tracé.
angleDeDepart et angleDArrivee type:Nombresont les position d’angles (en radian) dans le cercle trigonométrique.
sensInverse type:Booléen définit si l’on dessine dans le sens des aiguilles d’une montre ou le sens opposé.

L’inconvénient de la fonction arc, c’est qu’elle ne permet pas de dessiner des « parts de tarte », nous allons être obligés de contourner le problème en utilisant un masque.

Réaliser une "part de tarte"

Voici donc la fonction qui va nous permettre de dessiner une « part de tarte » :

 
//pour simplifier la notation, définissons une variable PI
var PI = Math.PI;
 
/*
paramètres :
x,y : position de l'horloge dans le canvas
r : le rayon de la part
a : l'angle formé par la part (en radian)
step : détermine l'angle total afficher (angle affiché = a*step)
fillColor, maskColor : les couleurs de la part et du masque
target : passer ici l'id du canvas cible
*/
function DrawSlice(x,y,r,a,step,fillColor,maskColor,target){
	var canvas = document.getElementById(target);
	var ctx = canvas.getContext("2d");		
 
	//on créé le masque d'arrière plan qui est un disque complet
	ctx.beginPath();
	ctx.fillStyle=maskColor;
	ctx.arc(x,y,r,0,2*PI,true);
	ctx.fill();
 
	//on dessine ensuite notre demi tarte
	ctx.beginPath();
	ctx.fillStyle = fillColor;
	ctx.strokeStyle = maskColor;
	ctx.lineWidth = 1;
	ctx.arc(x,y,r,step*a-PI/2,step*a-PI/2+PI,true);
	ctx.fill();
 
	if(step*a-PI/2 > PI/2){
	//si notre tarte représente plus de la moitié d'un disque
		ctx.beginPath();
		ctx.fillStyle=fillColor;
		ctx.arc(x,y,r,3*PI/2,PI/2,false);
		ctx.fill();
 
	}else{
	//sinon on masque la partie gauche
		ctx.beginPath();
		ctx.fillStyle=maskColor;
		ctx.arc(x,y,r,3*PI/2,PI/2,true);
		ctx.fill();
		ctx.stroke();
	}
 
	//on dessine ensuite le masque centrale.
	//si le rayon de la part à dessiner est inférieur à 20 on occulte l'inctruction
	//20 correspond à l'espacement entre chaque cercle
	if(r > 20){
		ctx.beginPath();
		ctx.fillStyle=maskColor;
		ctx.arc(x,y,r-20,0,2*PI,true);
		ctx.fill();
	}
}

Notre fonction de dessin est prête, préparons maintenant la fonction qui construira l’horloge :

function chrono(){
	var date = new Date();
	var canvas = document.getElementById("chrono");
 
	//on filtre les navigateurs ne comprenant pas les canvas
	if(canvas.getContext){
		var ctx = canvas.getContext("2d");
		ctx.clearRect(0,0,500,500);
 
		//part des heures
		DrawSlice(100,100,100,PI/12,date.getHours(),"#97BF4F","#FFFFFF","chrono");
		//part des minutes
		DrawSlice(100,100,70,PI/30,date.getMinutes()+1,"#999999","#FFFFFF","chrono");
		//part des secondes
		DrawSlice(100,100,40,PI/30,date.getSeconds()+1,"#666666","#FFFFFF","chrono");
		//part des dixièmes de seconde
		DrawSlice(100,100,10,PI/5,Math.floor(date.getMilliseconds()/100)+1,"#333333","#FFFFFF","chrono");
 
		//on affiche l'heure au format texte
		document.getElementById("clock").innerHTML = 
			"<span id='hour'>"+date.getHours()+
			"</span> : <span id='minute'>"+date.getMinutes()+
			"</span>' <span id='second'>"+date.getSeconds()+
			"</span>\" <span id='millisecond'>"+Math.floor(date.getMilliseconds()/100)+"</span>";
 
	}
	setTimeout("chrono()",100);
}

Tout est prêt, il ne manque que l’allumage !

<body onload="chrono()">
</body>

Nous sommes arrivés au terme de ce deuxième tutoriel, si certains aspects vous ont paru obscurs ou qu’une explication s’avère nécessaire n’hésitez pas à laisser un commentaire !

2 commentaires

  1. nfroidure dit :

    Belle utilisation de canvas. Je connaissais pas le concept de l’horloge polaire, mais c’est assez sympa, ça me rappelle la trigo ;) .

  2. [...] This post was mentioned on Twitter by Guilhem Marty, Nicolas Froidure. Nicolas Froidure said: Cool RT: @le_pixel: Créer une PolarClock avec Javascript et les Canvas => http://is.gd/d35IA [...]

Laisser un commentaire