4
Componentes

Reloj Digital

Reloj digital con visualización en tiempo real, cronómetro y cuenta regresiva personalizable.

Reloj Digital

Descripción

Este proyecto es un versátil reloj digital que ofrece tres modos de operación fundamentales: un reloj en tiempo real, un cronómetro preciso y un temporizador de cuenta regresiva totalmente personalizable. La singularidad de este reloj radica en la forma en que sus dígitos son renderizados utilizando el API de Canvas 2D, lo que permite una visualización segmentada y personalizable del color. Su interfaz dinámica permite alternar entre modos y controlar las funciones de temporización con facilidad, presentando una solución robusta para diversas necesidades de cronometraje digital.

Características clave

  • Múltiples Modos:

    Soporta tres modos principales: reloj digital en tiempo real, cronómetro y temporizador de cuenta regresiva.

  • Dígitos Personalizables:

    Los dígitos se dibujan usando el API de Canvas 2D, permitiendo cambiar el color de la pantalla.

  • Cronómetro:

    Funcionalidad de cronómetro con inicio, pausa/continuación y reinicio.

  • Temporizador de Cuenta Regresiva:

    Permite ajustar horas, minutos y segundos, con controles para añadir/restar tiempo y un indicador visual de finalización (animación de los dígitos).

  • Control de Visibilidad:

    Los controles de los temporizadores (botones de añadir/restar tiempo) aparecen y desaparecen dinámicamente según el modo seleccionado.

  • Formatos de Hora:

    Los números se muestran siempre con dos dígitos (ej. '05' en lugar de '5').

Aspectos destacados del código

  • API de Canvas 2D para Dibujo de Dígitos:

    Funciones modulares (createSegmentOne a createSegmentSeven) que utilizan ctx.beginPath(), ctx.lineTo(), ctx.fill(), y ctx.stroke() para construir cada segmento de los números de 7-segmentos, permitiendo un control granular sobre su apariencia.

  • function createSegmentOne(context) {
        context.beginPath();
        context.moveTo(15, 15);
        context.lineTo(30, 0);
        context.lineTo(110, 0);
        context.lineTo(125, 15);
        context.lineTo(110, 30);
        context.lineTo(30, 30);
        context.lineTo(15, 15);
        context.fill();
        context.stroke();
    }
  • Lógica de Renderizado de Números:

    La función createNumber toma un dígito y un contexto de canvas para dibujar el número correspondiente, seleccionando y activando los segmentos necesarios, y limpiando el canvas antes de redibujar.

  • function createNumber(number, context) {
        context.clearRect(0, 0, 250, 460);
        createBase(context);
        context.fillStyle = digitColor;
        context.lineWidth = 5;
        context.strokeStyle = "rgb(24, 24, 24)";
        switch (number) {
            case 0:
                createSegmentOne(context);
                // ... (other segments for 0)
                break;
            case 1:
                createSegmentTwo(context);
                createSegmentThree(context);
                break;
            // ... cases for other numbers
        }
    }
  • Gestión de Modos y Visibilidad de UI:

    La función changeOptionSelect controla qué elementos de la interfaz (botones de control, sliders de ajuste) son visibles u ocultos, adaptando la UI según si se selecciona el reloj, cronómetro o temporizador.

  • function changeOptionSelect() {
        optionSelected = selectOption.value;
        // ... logic to hide/show buttons and titles based on optionSelected
        if (optionSelected == 3) { // Timer mode
            buttonStart.style.visibility = "visible";
            // ... show other timer controls
        } if (optionSelected == 2) { // Chronometer mode
            buttonStart.style.visibility = "visible";
            // ... hide timer-specific controls
        }
        AnimationNormal();
    }
  • Actualización en Tiempo Real con `setInterval`:

    Múltiples setInterval se utilizan para gestionar la lógica de actualización: uno para el reloj digital (countSeconds) y otro para las operaciones del cronómetro (Chronometer) y temporizador (Timer), asegurando una sincronización precisa cada segundo.

  • setInterval(() => {
        if (optionSelected == 1) {
            countSeconds();
        }
    }, 1000);
    
    setInterval(() => {
        if (optionSelected == 3 && start) {
            Timer();
        }
        if (optionSelected == 2 && start) {
            Chronometer();
        }
    }, 1000);
  • Lógica de Cronómetro (Stopwatch):

    La función Chronometer incrementa los segundos, minutos y horas, manejando los desbordamientos para un conteo continuo, y actualiza los dígitos en el Canvas.

  • function Chronometer() {
        secondsChronometer++;
        if (secondsChronometer == 60) {
            secondsChronometer = 0;
            minutesChronometer++;
        }
        if (minutesChronometer == 60) {
            minutesChronometer = 0;
            hoursChronometer++;
        }
    
        createNumber(addZero(hoursChronometer)[0], ctxDigitHour_1);
        createNumber(addZero(hoursChronometer)[1], ctxDigitHour_2);
        // ... update other digits
    }
  • Lógica de Temporizador (Countdown):

    La función Timer decrementa el tiempo, gestiona la lógica de 'préstamo' entre segundos, minutos y horas, y detiene el temporizador cuando llega a cero, activando una animación de finalización.

  • function Timer() {
        if (secondsTimer == 0 || secondsTimer == -1) {
            secondsTimer = 60;
            if (minutesTimer == 0 && hoursTimer == 0) {
                start = false;
                // ... reset button state, call TimerFinishied, and return
                return;
            }
        }
        secondsTimer--;
        // ... logic for minutes and hours decrement
        createNumber(addZero(hoursTimer)[0], ctxDigitHour_1);
        createNumber(addZero(hoursTimer)[1], ctxDigitHour_2);
        // ... update other digits
    }
  • Control de Inicio/Pausa/Reseteo:

    La función TimerStart gestiona el estado de reproducción (inicio/pausa/continuar) de las funciones de cronómetro y temporizador, incluyendo la actualización del texto y estilo del botón, y la función Reset devuelve todos los contadores a cero y restablece la UI.

  • function TimerStart() {
        if (((hoursTimer != 0 || minutesTimer != 0 || secondsTimer != 0) && optionSelected == 3) || optionSelected == 2) {
            if (!start) {
                start = true;
                buttonStart.style.background = '#8ad4cd';
                buttonStart.textContent = "PAUSE";
            } else {
                start = false;
                buttonStart.style.background = '#e0e0e0';
                buttonStart.textContent = "CONTINUE";
            }
        } else {
            alert("Favor de elegir el tiempo!");
            buttonStart.style.background = '#e0e0e0';
            buttonStart.textContent = "START";
        }
    }
  • Animación de Finalización del Temporizador:

    TimerFinishied aplica animaciones CSS a los elementos del Canvas que muestran los dígitos, creando un efecto visual llamativo para indicar que el temporizador ha terminado, mientras AnimationNormal revierte estos estilos.

  • function TimerFinishied() {
        digitSecond_2.style.animation = "aumentar 1s infinite alternate ease-in-out";
        digitSecond_1.style.animation = "aumentar 1s infinite alternate ease-in-out ";
        // ... apply animation to other digit canvases
    }
    
    function AnimationNormal() {
        digitSecond_2.style.animation = "normal";
        // ... remove animation from other digit canvases
    }

Desafíos técnicos

  • Gestión de Múltiples Modos:

    Implementar y alternar entre las tres funcionalidades (reloj, cronómetro, temporizador) de forma fluida, asegurando que los contadores y la UI se comporten correctamente en cada modo.

  • Sincronización Precisa del Tiempo:

    Mantener el reloj, cronómetro y temporizador actualizados cada segundo sin errores de desfase, lo que implica un manejo cuidadoso de setInterval y las operaciones de tiempo.

  • Renderizado Eficiente de Dígitos en Canvas:

    Dibujar y redibujar múltiples dígitos de 7-segmentos en Canvas en tiempo real, optimizando el rendimiento para evitar parpadeos o lentitud.

  • Lógica de Temporizador Compleja:

    Desarrollar la lógica de cuenta regresiva del temporizador, incluyendo el manejo de minutos y horas cuando los segundos llegan a cero, y la detección del final del conteo.

  • Manipulación Dinámica del DOM y UI Reactiva:

    Mostrar u ocultar elementos de la interfaz de usuario de forma condicional y actualizar sus propiedades (como el color o el texto de los botones) en respuesta a las acciones del usuario y los cambios de estado.

Aprendizajes obtenidos

  • Diseño de Componentes Modulares:

    Aprendí a descomponer la interfaz digital en segmentos y dígitos individuales, facilitando su dibujo y reutilización a través del Canvas API.

  • Gestión Avanzada de Estados en JavaScript:

    Reforcé mi capacidad para manejar estados complejos (reloj, cronómetro, temporizador, inicio/pausa) y cómo estos influyen en la lógica y la interfaz de usuario.

  • Aplicaciones del Objeto `Date` y `setInterval`:

    Profundicé en la aplicación práctica de Date para obtener y manipular el tiempo, y setInterval para ejecutar tareas recurrentes en tiempo real.

  • Técnicas de Renderizado de Gráficos con Canvas:

    Mejoré mis habilidades en el dibujo programático de formas y la gestión de contextos de Canvas para crear interfaces visuales personalizadas.

  • Mejora de UI/UX:

    Entendí la importancia de la retroalimentación visual (como la animación de finalización del temporizador) y la adaptación de la UI para una experiencia de usuario intuitiva.

Posibles mejoras / Ideas a implementar

  • Sonidos de Alarma/Tictac:

    Añadir efectos de sonido para el final del temporizador o un tictac opcional para el reloj/cronómetro.

  • Personalización de Digitos:

    Permitir al usuario elegir entre diferentes estilos de fuente o colores para cada par de dígitos.

  • Funcionalidad de Vueltas (Laps) en Cronómetro:

    Agregar la capacidad de registrar tiempos de vuelta en el modo cronómetro.

  • Preajustes de Temporizador:

    Permitir guardar y cargar configuraciones de temporizador predefinidas.

  • Soporte de Zonas Horarias:

    Opción para mostrar la hora en diferentes zonas horarias.

  • Modo de Pantalla Completa:

    Opción para expandir el reloj a pantalla completa.

Información

Componentes

2022-11-30

JavaScript

Etiquetas

clocktimercountdownsetIntervalUIcanvasDOM Manipulationfrontendtime