Todo comenzó la semana pasada cuando vi un diseño super precioso de un reloj digital en dribbble. Inmediatamente sentí la tentación de convertirlo en un reloj que se pudiese utilizar en la web y compartirlo con los lectores programacion.net. Si deseas saber cómo lo llevé a cabo, ¡sigue leyendo!
El HTML
El reloj no necesita una gran cantidad de HTML. Esto se debe a que una gran parte de sus componentes, como los nombres de los días de semana y el código para los dígitos, se generan dinámicamente. Aquí tienes el markup que necesitas tener en tu página web para utilizar el reloj:
index.html
<div id="clock" class="light">
<div class="display">
<div class="weekdays"></div>
<div class="ampm"></div>
<div class="alarm"></div>
<div class="digits"></div>
</div>
</div>
El elemento principal, el div #clock, contiene el .display, que a su vez se convierte en la lista de los días de semana, la etiqueta AM / PM, el icono de alarma y la hora. Y aquí está el markup generado para cada uno de los dígitos:
<div class="zero">
<span class="d1"></span>
<span class="d2"></span>
<span class="d3"></span>
<span class="d4"></span>
<span class="d5"></span>
<span class="d6"></span>
<span class="d7"></span>
</div>
El elemento .digits contendrá 6 de esos divs con spans, uno por cada dígito de la hora. Como puedes ver en el snippet anterior, estos divs obtienen un nombre de clase de cero a nueve, y contienen siete elementos span con clases particulares. Estos tramos son los segmentos de los dígitos, como en los relojes digitales antiguos:
Su aspecto está desarrollado íntegramente en CSS y fijan la opacidad a 0 (opacity:0) por defecto. La clase asignada a su div padre es lo que los hace visibles. Aquí está el CSS para el cero:
assets/css/styles.css
#clock .digits div.zero .d1, #clock .digits div.zero .d3, #clock .digits div.zero .d4, #clock .digits div.zero .d5, #clock .digits div.zero .d6, #clock .digits div.zero .d7{ opacity:1; }
Todos los segmentos son visibles, a excepción de el del centro (sino sería un 8). He añadido una propiedad de transición de CSS3 a todos estos tramos, que animan la opacidad al cambiar de número.
Hay un más código CSS en la hoja de estilo, pero no es relevante para lo que estamos hablando, la verdad. Creo que la mejor manera de aprender cómo funciona el CSS es inspeccionando el código con herramientas para desarrolladores como Firebug, el inspector de Chrome o las herramientas de desarrollo del navegador que habitualmente utilices.
El código jQuery
Para desarrollar el reloj, vamos a tener que utilizar jQuery para generar el markup para cada uno de los dígitos, y establecer un temporizador para actualizar las clases cada segundo. Para que todo sea más llevadero, vamos a utilizar la biblioteca moment.js (que ya utilizamos en el artículo anterior) para compensar las funciones de JavaScript en el tratamientos de fechas y horas. Una de las características en las que jQuery suele no funcionar tan bien.
assets/js/script.js
$(function(){
// Cache some selectors
var clock = $('#clock'),
alarm = clock.find('.alarm'),
ampm = clock.find('.ampm');
// Map digits to their names (this will be an array)
var digit_to_name = 'zero one two three four five six seven eight nine'.split(' ');
// This object will hold the digit elements
var digits = {};
// Positions for the hours, minutes, and seconds
var positions = [
'h1', 'h2', ':', 'm1', 'm2', ':', 's1', 's2'
];
// Generate the digits with the needed markup,
// and add them to the clock
var digit_holder = clock.find('.digits');
$.each(positions, function(){
if(this == ':'){
digit_holder.append('<div class="dots">');
}
else{
var pos = $('<div>');
for(var i=1; i<8; i++){
pos.append('<span class="d' + i + '">');
}
// Set the digits as key:value pairs in the digits object
digits[this] = pos;
// Add the digit elements to the page
digit_holder.append(pos);
}
});
// Add the weekday names
var weekday_names = 'MON TUE WED THU FRI SAT SUN'.split(' '),
weekday_holder = clock.find('.weekdays');
$.each(weekday_names, function(){
weekday_holder.append('<span>' + this + '</span>');
});
var weekdays = clock.find('.weekdays span');
// Run a timer every second and update the clock
(function update_time(){
// Use moment.js to output the current time as a string
// hh is for the hours in 12-hour format,
// mm - minutes, ss-seconds (all with leading zeroes),
// d is for day of week and A is for AM/PM
var now = moment().format("hhmmssdA");
digits.h1.attr('class', digit_to_name[now[0]]);
digits.h2.attr('class', digit_to_name[now[1]]);
digits.m1.attr('class', digit_to_name[now[2]]);
digits.m2.attr('class', digit_to_name[now[3]]);
digits.s1.attr('class', digit_to_name[now[4]]);
digits.s2.attr('class', digit_to_name[now[5]]);
// The library returns Sunday as the first day of the week.
// Stupid, I know. Lets shift all the days one position down,
// and make Sunday last
var dow = now[6];
dow--;
// Sunday!
if(dow < 0){
// Make it last
dow = 6;
}
// Mark the active day of the week
weekdays.removeClass('active').eq(dow).addClass('active');
// Set the am/pm text:
ampm.text(now[7]+now[8]);
// Schedule this function to be run again in 1 sec
setTimeout(update_time, 1000);
})();
// Switch the theme
$('a.button').click(function(){
clock.toggleClass('light dark');
});
});
La pieza más importante del código de nates es la función update_time. Dentro de ella, obtenemos la hora actual como un string, y la utilizamos para rellenar los elementos del reloj y establecer las clases correctas para los dígitos.
¡Con esto nuestro reloj digital estaría listo! En el siguiente artículo añadiremos soporte para configurar alarmas y reproducirlas con audio en HTML5.