Creando Movimiento

Animaciones Complejas con JavaScript

Vamos más allá del CSS: cómo usar JS para animaciones interactivas y fluidas.

Comenzar

El Desafío: Más Allá de CSS

Las animaciones CSS son fantásticas para transiciones y efectos visuales predefinidos, como los que hemos visto para hacer aparecer elementos al hacer scroll. Sin embargo, cuando buscamos una interacción más dinámica, como un elemento que reacciona en tiempo real a la posición del ratón de forma orgánica y suave, necesitamos recurrir a JavaScript.

JavaScript nos permite calcular posiciones continuamente y actualizar los estilos de los elementos en cada frame disponible, abriendo la puerta a animaciones mucho más complejas y personalizadas.

En esta entrada, vamos a construir un efecto visualmente atractivo: un "seguidor viscoso" (gooey follower) que persigue al cursor con una estela elástica.

Paso 1: Estructura HTML y CSS

La base es sencilla. Necesitamos un contenedor donde ocurrirá la animación y varios elementos (círculos) que formarán nuestro seguidor y su estela.

HTML

Dentro de nuestro contenedor `.interactive-example`, crearemos dinámicamente los círculos con JavaScript, pero así es como se verían si los pusiéramos directamente:

<div class="interactive-example"> <div class="follower-circle main"></div> <div class="follower-circle"></div> <div class="follower-circle"></div> <p class="info-text">Mueve el ratón aquí dentro</p> </div>

CSS

Definimos el estilo base para todos los círculos seguidores y uno especial para el círculo principal (`.main`). Usamos `position: absolute` para poder moverlos libremente y `mix-blend-mode: screen` y `filter: blur()` para conseguir el efecto "viscoso" cuando se superponen.

:root { --num-circles: 5; --circle-base-size: 25px; --circle-color: var(--color-accent-proto); --lerp-factor-base: 0.15; } .interactive-example { margin-top: 40px; margin-bottom: 40px; padding: 50px; background-color: var(--color-bg-light); border: 1px solid var(--color-border); border-radius: 8px; position: relative; min-height: 300px; overflow: hidden; cursor: none; } .follower-circle { position: absolute; border-radius: 50%; background-color: var(--circle-color); pointer-events: none; mix-blend-mode: screen; z-index: 11; opacity: 0.7; box-shadow: 0 0 15px var(--circle-color); filter: blur(2px); top: -50px; left: -50px; } .follower-circle.main { width: var(--circle-base-size); height: var(--circle-base-size); z-index: 12; opacity: 1; filter: blur(0); box-shadow: 0 0 20px var(--circle-color); } .info-text { text-align: center; color: var(--color-text-secondary); font-style: italic; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1; }

Paso 2: La Magia con JavaScript

Ahora, implementamos la lógica para crear los círculos, seguir el ratón y animar la estela con diferentes velocidades.

El Código JS

const interactiveArea = document.querySelector('.interactive-example'); const numCircles = 6; const circles = []; const coords = { x: 0, y: 0 }; const lerpFactorBase = 0.18; if (interactiveArea) { for (let i = 0; i < numCircles; i++) { const circle = document.createElement('div'); circle.classList.add('follower-circle'); let size; if (i === 0) { circle.classList.add('main'); size = 25; } else { size = Math.max(5, 25 - i * 3.5); circle.style.width = `${size}px`; circle.style.height = `${size}px`; circle.style.opacity = `${0.7 - i * 0.1}`; } interactiveArea.appendChild(circle); circles.push({ el: circle, x: interactiveArea.offsetWidth / 2, y: interactiveArea.offsetHeight / 2, size: size }); } interactiveArea.addEventListener('mousemove', (e) => { const rect = interactiveArea.getBoundingClientRect(); coords.x = e.clientX - rect.left; coords.y = e.clientY - rect.top; }); interactiveArea.addEventListener('mouseleave', () => { coords.x = interactiveArea.offsetWidth / 2; coords.y = interactiveArea.offsetHeight / 2; }); function animateFollowers() { let prevX = coords.x; let prevY = coords.y; circles.forEach((circle, index) => { const targetX = index === 0 ? coords.x : prevX; const targetY = index === 0 ? coords.y : prevY; const lerp = lerpFactorBase + index * 0.01; circle.x += (targetX - circle.x) * lerp; circle.y += (targetY - circle.y) * lerp; circle.el.style.transform = `translate(calc(${circle.x}px - 50%), calc(${circle.y}px - 50%))`; prevX = circle.x; prevY = circle.y; }); requestAnimationFrame(animateFollowers); } setTimeout(animateFollowers, 100); }

Puntos Clave

Paso 3: ¡El Resultado!

Ahora, al mover el ratón sobre el área interactiva, verás el efecto "gooey follower" en acción. Un círculo principal seguido por una estela de círculos más pequeños que se mueven de forma orgánica y fluida.

Mueve el ratón aquí dentro

Este tipo de animación, basada en `requestAnimationFrame` y cálculos de interpolación, es mucho más versátil que las animaciones CSS puras. Nos permite crear efectos que responden directamente a la interacción del usuario o a datos cambiantes, abriendo un mundo de posibilidades para interfaces dinámicas y atractivas.

Experimentar con el número de círculos, sus tamaños, los factores de `lerp` y las propiedades CSS como `mix-blend-mode` o `filter` puede llevar a resultados visuales muy diferentes y creativos.