Les styles définis dans l'en-tête sont :


.wrapper {
	display: inline-block; 
	font-family: square, sans-serif; 
	font-size: 4em; 
	color: #ffcc33;
	background-color: #000;
	height: 1em;
    width: .6em;
	overflow: hidden; /*  */
	} 
	
.digit, .digit_right, .digit_down {
    height: 2em;
    width: 1.2em;
    text-align: right;   
    } 

.digit {
    margin-left: -0.6em;
    margin-top: -1.2em;
    -webkit-transition: margin-top 3s ease-out;
    -moz-transition: margin-top 3s ease-out;
    transition: margin-top 3s ease-out;
    }     
    
.digit_right {
    margin-left: 0;
    margin-top: -1.2em;
    -webkit-transition: margin-left 3s ease-out;
    -moz-transition: margin-left 3s ease-out;
    transition: margin-left 3s ease-out;
    } 
    
.digit_down {
    margin-left: 0;
    margin-top: 0;
    } 

Le code suivant figure dans le corps du document : 


<div class= 'wrapper'><div id= 'hours_first_digit_id' class= 'digit'></div></div>
<div class= 'wrapper'><div id= 'hours_second_digit_id' class= 'digit'></div></div><br>
<div class= 'wrapper'><div id= 'minutes_first_digit_id' class= 'digit'></div></div>
<div class= 'wrapper'><div id= 'minutes_second_digit_id' class= 'digit'></div></div>

Le code suivant figure en bas de page :


<script type="text/javascript">

const hours_first_digit= document.getElementById('hours_first_digit_id');
const hours_second_digit= document.getElementById('hours_second_digit_id');
const minutes_first_digit= document.getElementById('minutes_first_digit_id');
const minutes_second_digit= document.getElementById('minutes_second_digit_id');
var h1; var h2; var m1; var m2;

function init_clock() {
	var temp;
    var first_digit;
    var second_digit;
    var now = new Date();
    
    temp= now.getHours() / 10;
    first_digit= Math.floor(temp); 
    h1= first_digit; //initialisation pour l'horloge animée
    hours_first_digit.innerHTML= '
' + first_digit; second_digit= Math.round((temp - Math.floor(temp))*10); h2= second_digit; hours_second_digit.innerHTML= '
' + second_digit; temp= now.getMinutes() / 10; first_digit= Math.floor(temp); m1= first_digit; minutes_first_digit.innerHTML= '
' + first_digit; second_digit= Math.round((temp - Math.floor(temp))*10); m2= second_digit; minutes_second_digit.innerHTML= '
' + second_digit; } function animate_clock() { var temp; var now = new Date(); var first_digit; var second_digit; temp= now.getHours() / 10; first_digit= Math.floor(temp); if ((first_digit != h1) && (hours_first_digit.className == 'digit')) { hours_first_digit.className= "digit_right"; } else if ((first_digit != h1) && (hours_first_digit.className == "digit_right")) { hours_first_digit.className= "digit_down"; hours_first_digit.innerHTML= '
' + first_digit; } else if ((first_digit != h1) && (hours_first_digit.className == "digit_down")) { hours_first_digit.className= "digit"; h1 = first_digit; } second_digit= Math.round((temp - first_digit)*10); if ((second_digit != h2) && (hours_second_digit.className == 'digit')) { hours_second_digit.className= "digit_right"; } else if ((second_digit != h2) && (hours_second_digit.className == "digit_right")) { hours_second_digit.className= "digit_down"; hours_second_digit.innerHTML= '
' + second_digit; } else if ((second_digit != h2) && (hours_second_digit.className == "digit_down")) { hours_second_digit.className= "digit"; h2 = second_digit; } temp= now.getMinutes() / 10; first_digit= Math.floor(temp); if ((first_digit != m1) && (minutes_first_digit.className == 'digit')) { minutes_first_digit.className= "digit_right"; } else if ((first_digit != m1) && (minutes_first_digit.className == "digit_right")) { minutes_first_digit.className= "digit_down"; minutes_first_digit.innerHTML= '
' + first_digit; } else if ((first_digit != m1) && (minutes_first_digit.className == "digit_down")) { minutes_first_digit.className= "digit"; m1 = first_digit; } second_digit= Math.round((temp - first_digit)*10); if ((second_digit != m2) && (minutes_second_digit.className == 'digit')) { minutes_second_digit.className= "digit_right"; } else if ((second_digit != m2) && (minutes_second_digit.className == "digit_right")) { minutes_second_digit.className= "digit_down"; minutes_second_digit.innerHTML= '
' + second_digit; } else if ((second_digit != m2) && (minutes_second_digit.className == "digit_down")) { minutes_second_digit.className= "digit"; m2 = second_digit; } } init_clock(); window.onload= function() { setInterval('animate_clock()', 2000); }; </script>

La fonction init_clock() comporte tout le nécessaire pour afficher l'horloge; il suffirait de l'appeler périodiquement avec setInterval().

Pour assurer l'animation on stocke la valeur initiale de chacune des quatre cases de l'horloge dans les variables h1, h2, m1, m2; l'animation d'une case sera déclenchée si la valeur souhaitée (issue de new date()) est différente de la valeur de la case. Chaque case est enveloppée par une division wrapper qui ne montre que le quart de chaque case, le reste étant invisible (overflow: hidden;). L'animation fait disparaitre le contenu par déplacement vers la droite; pendant que le contenu est masqué on déplace ce contenu vers le bas et on en change la valeur; puis ont révèle cette valeur par un déplacement vers le haut.

L'animation étant assurée par des CSS, on doit disposer de 3 classes CSS correspondant à chaque position: normale (visible), à droite et en bas; l'animation est déclenchée en javascript par le changement de classe de la case (objet.className= )

Bibliographie

 ↑ Clocks.
Des horloges analogiques.