¿Alguna vez has querido crear una experiencia web que no solo sea visualmente atractiva, sino que también cuente una historia al interactuar con ella? Hoy vamos a desglosar cómo construí el efecto "Eclipse de Amor".
Aunque inicialmente pensé en usar Canvas, decidí que la verdadera magia residía en la manipulación pura del DOM usando HTML, CSS y JavaScript. El objetivo: permitir al usuario arrastrar la luna con su dedo (o ratón) para revelar la luz del sol y un mensaje especial.
El mejor código es aquel que conecta la interacción física del usuario con una emoción visual.
A continuación, te explico la magia detrás de este desarrollo paso a paso.
La estructura base (HTML)
Para mantener las cosas limpias, nuestra estructura necesita tres capas principales: el fondo estrellado, el contenedor de las frases y, por supuesto, nuestro sistema solar en miniatura.
<div class="stars" id="starsContainer"></div>
<div class="phrase-container">
<div id="text-display" class="phrase"></div>
</div>
<div class="scene-container">
<div class="corona" id="corona"></div>
<div class="sun" id="sun"></div>
<div class="moon" id="moon"></div>
</div>
<div class="controls">ARRASTRA LA LUNA PARA VER EL MENSAJE</div>Dando vida al espacio (CSS)
El secreto para que un eclipse luzca realista sin usar imágenes es el uso inteligente de box-shadow y gradientes radiales.
Definimos variables globales para facilitar el cambio de temas. Fíjate cómo construimos el sol y la luna usando simples divs redondeados al 50%:
:root {
--bg-color: #050508;
--sun-color: #ffaa00;
--sun-glow: #ff5500;
--moon-color: #08080c;
}
.sun {
background: radial-gradient(circle at 30% 30%, #fff, var(--sun-color));
box-shadow: 0 0 60px var(--sun-glow);
}
.moon {
background: var(--moon-color);
box-shadow: inset -20px -10px 40px rgba(0,0,0,0.9);
cursor: grab;
will-change: transform; /* Optimización de rendimiento */
}La lógica de arrastre (JavaScript)
Aquí es donde ocurre la verdadera interactividad. Necesitábamos que la luna fuera arrastrable tanto en computadoras de escritorio como en dispositivos móviles. Para lograrlo, escuchamos dos tipos de eventos:
Eventos de Mouse: mousedown, mousemove, mouseup.
Eventos Táctiles (Touch): touchstart, touchmove, touchend.
Calculando la posición
Cuando el usuario hace clic o toca la luna, guardamos la posición inicial (startX). A medida que se mueve, calculamos la diferencia (deltaX) y usamos una transformación CSS para mover la luna en el eje X (translateX).
function drag(e) {
if (!isDragging) return;
const clientX = (e.type.includes('mouse')) ? e.clientX : e.touches[0].clientX;
const deltaX = clientX - startX;
currentTranslate = prevTranslate + deltaX;
if (currentTranslate > 220) currentTranslate = 220;
if (currentTranslate < -220) currentTranslate = -220;
updateScene(currentTranslate);
}Actualizando la escena dinámica
La función updateScene es el cerebro del eclipse. Dependiendo de qué tan lejos esté la luna del centro (calculando la distancia absoluta), hacemos varias cosas matemáticas maravillosas:
Aumentamos el resplandor (box-shadow) del sol.
Aclaramos el color de fondo del body gradualmente.
Si la distancia supera los 50 píxeles, disparamos la función startPhraseSequence() que hace aparecer nuestras frases románticas usando clases CSS transicionables.
Conclusión
Crear experiencias interactivas no siempre requiere librerías complejas. Entender cómo los eventos táctiles se comunican con el DOM te permite crear componentes altamente inmersivos con muy pocas líneas de código.
Si te ha gustado este efecto, te animo enviárselo a esa persona especial. ¡Feliz código!
