¿Te has preguntado alguna vez cómo se construye un reloj digital interactivo
directamente en la web? ¡La respuesta es más fascinante de lo que
imaginas! exploraremos cómo las poderosas combinaciones de HTML para la
estructura, CSS para el estilo y JavaScript para la lógica viva se unen para
dar vida a un elegante reloj directamente en tu navegador.
Este es el "lienzo" donde se dibuja el reloj. Piensa en él como un dibujo que se actualiza constantemente.
<canvas id="relojCanvas"></canvas>
Aquí se define el estilo de la página y del reloj:
El fondo de la página es oscuro (#111).
El reloj tiene un fondo semitransparente, bordes redondeados y una sombra suave para que se vea mejor.
El reloj tiene un tamaño de 600x600 píxeles.
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #111; /* Fondo más oscuro */
overflow: hidden; /* Evita scrollbars */
font-family: 'Arial', sans-serif;
}
canvas {
background-color: rgba(0, 0, 0, 0.8); /* Fondo del canvas semi-transparente */
border-radius: 15px; /* Bordes redondeados */
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6); /* Sombra suave */
/* Tamaño del canvas ajustado para mejor visualización */
width: 600px; /* Aumentado un poco el tamaño */
height: 600px;
}
Obtener el lienzo y el contexto: Se obtiene el elemento canvas del HTML y su contexto de dibujo 2D.
Variables y constantes: Se define la constante PI para cálculos de ángulos.
Función resizeCanvas(): Establece el ancho y el alto del canvas.
Evento window.addEventListener('resize', resizeCanvas): Asegura que el tamaño del canvas se actualice cuando cambia el tamaño de la ventana.
Función drawReloj():
Limpia el canvas.
Calcula el centro y el radio del reloj.
Obtiene la hora actual.
Dibuja el fondo, el borde, las marcas de las horas y los minutos, y las agujas del reloj.
Función drawHand(): Dibuja una aguja del reloj con un gradiente y una sombra.
Actualizar el reloj: La función setInterval llama a drawReloj() cada 40 milisegundos para actualizar la visualización del reloj.
const canvas = document.getElementById('relojCanvas');
const ctx = canvas.getContext('2d');
const PI = Math.PI;
function resizeCanvas() {
canvas.width = 600; // Tamaño fijo para simplificar, puedes hacerlo dinámico si lo prefieres
canvas.height = 600;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
function drawReloj() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = Math.min(centerX, centerY) * 0.9; // Radio un poco más grande
const now = new Date();
const hours = now.getHours() % 12;
const minutes = now.getMinutes();
const seconds = now.getSeconds();
const milliseconds = now.getMilliseconds();
// Fondo del reloj con gradiente suave
const gradient = ctx.createRadialGradient(centerX, centerY, radius * 0.1, centerX, centerY, radius);
gradient.addColorStop(0, '#0a3242'); // Color inicial más oscuro
gradient.addColorStop(1, '#000'); // Color final negro
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Borde del reloj
ctx.lineWidth = 8;
ctx.strokeStyle = '#ddd';
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * PI);
ctx.stroke();
// Marcas de las horas (más estilizadas)
for (let i = 0; i < 12; i++) {
const angle = (i - 3) * (PI / 6);
const x = centerX + Math.cos(angle) * radius * 0.82; // Más cerca del borde
const y = centerY + Math.sin(angle) * radius * 0.82;
ctx.lineWidth = 3;
ctx.strokeStyle = '#eee';
ctx.beginPath();
ctx.moveTo(centerX + Math.cos(angle) * radius * 0.75, centerY + Math.sin(angle) * radius * 0.75); // Longitud de la marca
ctx.lineTo(x, y);
ctx.stroke();
}
// Marcas de los minutos (más delgadas y discretas)
for (let i = 0; i < 60; i++) {
if (i % 5 !== 0) { // No dibujar encima de las marcas de las horas
const angle = (i - 15) * (PI / 30);
const x = centerX + Math.cos(angle) * radius * 0.88;
const y = centerY + Math.sin(angle) * radius * 0.88;
ctx.lineWidth = 1;
ctx.strokeStyle = '#ccc'; // Color más claro
ctx.beginPath();
ctx.moveTo(centerX + Math.cos(angle) * radius * 0.85, centerY + Math.sin(angle) * radius * 0.85);
ctx.lineTo(x, y);
ctx.stroke();
}
}
// Aguja de las horas (con sombra y gradiente)
const hourAngle = (hours + minutes / 60) * (PI / 6) - PI / 2;
drawHand(centerX, centerY, radius * 0.5, hourAngle, 10, '#fff', '#333', 5);
// Aguja de los minutos (con sombra y gradiente)
const minuteAngle = (minutes + seconds / 60) * (PI / 30) - PI / 2;
drawHand(centerX, centerY, radius * 0.75, minuteAngle, 8, '#fff', '#666', 3);
// Aguja de los segundos (más delgada y con color llamativo)
const secondAngle = (seconds + milliseconds / 1000) * (PI / 30) - PI / 2;
drawHand(centerX, centerY, radius * 0.9, secondAngle, 3, '#f44336', '#f44336', 1);
// Centro del reloj (más pequeño y sutil)
ctx.beginPath();
ctx.arc(centerX, centerY, 4, 0, 2 * PI);
ctx.fillStyle = '#fff';
ctx.fill();
}
function drawHand(centerX, centerY, length, angle, width, color, shadowColor, shadowBlur) {
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(angle);
// Sombra de la aguja
ctx.shadowColor = shadowColor;
ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
// Gradiente para la aguja
const gradient = ctx.createLinearGradient(0, 0, length, 0);
gradient.addColorStop(0, 'rgba(255,255,255,0.2)');
gradient.addColorStop(1, color);
ctx.lineWidth = width;
ctx.strokeStyle = gradient;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(length, 0);
ctx.stroke();
ctx.restore();
}
setInterval(drawReloj, 40);
0 Comentarios