Back

Dale Vida a tu UI con Animaciones ScrollTrigger en GSAP

Dale Vida a tu UI con Animaciones ScrollTrigger en GSAP

Las animaciones basadas en scroll pueden transformar un sitio web estático en una experiencia interactiva y atractiva. Aunque las animaciones CSS son útiles para efectos básicos, crear animaciones sofisticadas activadas por scroll requiere una herramienta más potente. El plugin ScrollTrigger de GSAP es exactamente esa herramienta, permitiéndote crear animaciones pulidas y eficientes que se activan según la posición del scroll.

En esta guía, aprenderás cómo implementar animaciones ScrollTrigger que responden de manera natural al desplazamiento del usuario, con ejemplos prácticos que puedes usar en tus proyectos hoy mismo.

Puntos Clave

  • ScrollTrigger conecta las animaciones con la posición del scroll para experiencias interactivas
  • Usa scrub para vincular el progreso de la animación directamente con la posición del scroll
  • Fija elementos para crear efectos avanzados basados en scroll
  • Configura start y end para controlar con precisión cuándo se activan las animaciones
  • Usa markers durante el desarrollo para visualizar los puntos de activación

¿Qué es ScrollTrigger y Por Qué Usarlo?

ScrollTrigger es un plugin de GSAP que conecta las animaciones con la posición del scroll. A diferencia de las librerías básicas “on-scroll” que simplemente activan animaciones cuando los elementos entran en el viewport, ScrollTrigger ofrece control preciso sobre:

  • Cuándo las animaciones comienzan y terminan basándose en la posición del scroll
  • Cómo progresan las animaciones mientras los usuarios hacen scroll (scrubbing)
  • Fijar elementos mientras los usuarios hacen scroll más allá de ellos
  • Crear interacciones complejas basadas en scroll

¿El resultado? Animaciones que se sienten conectadas al desplazamiento del usuario en lugar de simplemente reproducirse cuando se activan.

Comenzando con ScrollTrigger

Primero, configuremos lo básico:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ScrollTrigger Demo</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
        }
        
        section {
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .spacer {
            height: 100vh;
        }
        
        .box {
            width: 200px;
            height: 200px;
            background-color: #3498db;
            border-radius: 8px;
        }
    </style>
</head>
<body>
    <div class="spacer"></div>
    
    <section>
        <div class="box"></div>
    </section>
    
    <div class="spacer"></div>
    
    <!-- GSAP and ScrollTrigger -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
    
    <script>
        // Register the plugin
        gsap.registerPlugin(ScrollTrigger);
        
        // Your animations will go here
    </script>
</body>
</html>

Animación Básica con ScrollTrigger

Comencemos con una animación simple que se activa cuando un elemento entra en el viewport:

gsap.to(".box", {
    scrollTrigger: ".box", // Elemento que activa la animación
    x: 300, // Mover 300px hacia la derecha
    rotation: 360, // Rotar 360 grados
    duration: 1.5, // Duración de la animación
    ease: "power2.out" // Función de easing
});

Este código mueve y rota la caja cuando entra en el viewport. Pero esto es solo rascar la superficie.

Entendiendo la Configuración de ScrollTrigger

Para desbloquear todo el potencial de ScrollTrigger, necesitamos entender sus opciones de configuración:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box", // Elemento que activa la animación
        start: "top center", // Comenzar cuando la parte superior de la caja toca el centro del viewport
        end: "bottom center", // Terminar cuando la parte inferior de la caja toca el centro del viewport
        toggleActions: "play pause reverse reset", // Acciones en entrar, salir, entrar de nuevo, salir de nuevo
        markers: true, // Muestra marcadores para debugging (eliminar en producción)
    },
    x: 300,
    rotation: 360,
    duration: 2
});

Las propiedades start y end definen cuándo la animación se activa y desactiva. El formato es "[posición del elemento trigger] [posición del viewport]".

toggleActions controla cómo se comporta la animación en cuatro momentos clave:

  1. Al entrar en el área de activación
  2. Al salir del área de activación
  3. Al entrar nuevamente en el área de activación mientras se desplaza hacia arriba
  4. Al salir del área de activación mientras se desplaza hacia arriba

Las opciones incluyen: play, pause, resume, reverse, restart, reset, complete, y none.

Creando Animaciones Impulsadas por Scroll con Scrub

La verdadera magia ocurre con la propiedad scrub, que vincula el progreso de la animación directamente con la posición del scroll:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box",
        start: "top center",
        end: "bottom center",
        scrub: true, // Vincula el progreso de la animación con la posición del scroll
        markers: true
    },
    x: 300,
    rotation: 360,
    backgroundColor: "#e74c3c"
});

Con scrub: true, la animación progresa mientras el usuario hace scroll, e incluso se revierte cuando se desplaza hacia atrás. Para una animación más suave, usa un valor numérico como scrub: 0.5 para agregar un ligero retraso.

Fijando Elementos Durante el Scroll

Una de las características más poderosas de ScrollTrigger es fijar elementos en su lugar mientras el usuario hace scroll:

gsap.to(".box", {
    scrollTrigger: {
        trigger: ".box",
        start: "center center",
        end: "+=300", // Terminar 300px después de la posición de inicio
        pin: true, // Fijar la caja en su lugar durante la animación
        scrub: 1,
        markers: true
    },
    x: 300,
    rotation: 360,
    scale: 1.5,
    backgroundColor: "#9b59b6"
});

Esto fija la caja en su lugar mientras la animación se reproduce, creando un efecto similar al parallax. El end: "+=300" significa que la animación termina después de desplazarse 300 píxeles más allá del punto de inicio.

Creando una Animación de Revelado

Creemos una animación de revelado práctica para texto o imágenes:

<div class="spacer"></div>

<section class="reveal-section">
    <div class="reveal-container">
        <h1 class="reveal-text">Animaciones Impulsadas por Scroll</h1>
        <p class="reveal-text">Crea experiencias de usuario atractivas con GSAP ScrollTrigger</p>
    </div>
</section>

<div class="spacer"></div>
.reveal-section {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.reveal-container {
    max-width: 800px;
    text-align: center;
    overflow: hidden;
}

.reveal-text {
    opacity: 0;
    transform: translateY(50px);
}
// Animación de revelado
gsap.utils.toArray('.reveal-text').forEach(text => {
    gsap.to(text, {
        scrollTrigger: {
            trigger: text,
            start: "top 80%", // Comenzar cuando la parte superior del texto está al 80% desde la parte superior del viewport
            toggleActions: "play none none none"
        },
        y: 0,
        opacity: 1,
        duration: 1,
        ease: "power2.out"
    });
});

Esto crea un efecto de revelado limpio mientras cada elemento de texto entra en el viewport.

Creando un Efecto Parallax

Los efectos parallax agregan profundidad a tu sitio web. Aquí te mostramos cómo crear uno:

<div class="parallax-container">
    <div class="parallax-bg"></div>
    <div class="parallax-content">
        <h1>Efecto Parallax</h1>
    </div>
</div>
.parallax-container {
    height: 100vh;
    position: relative;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
}

.parallax-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 120%; /* Altura extra para el movimiento */
    background-image: url('your-background-image.jpg');
    background-size: cover;
    background-position: center;
}

.parallax-content {
    position: relative;
    z-index: 1;
    color: white;
    text-align: center;
}
// Efecto parallax
gsap.to(".parallax-bg", {
    scrollTrigger: {
        trigger: ".parallax-container",
        start: "top bottom",
        end: "bottom top",
        scrub: true
    },
    y: -100, // Mover el fondo hacia arriba 100px mientras hacemos scroll
    ease: "none"
});

Esto crea un efecto parallax simple donde el fondo se mueve a una velocidad diferente que el primer plano.

Sección de Desplazamiento Horizontal

Crear una sección de desplazamiento horizontal es otro efecto impresionante:

<div class="spacer"></div>

<section class="horizontal-scroll">
    <div class="horizontal-container">
        <div class="panel">Panel 1</div>
        <div class="panel">Panel 2</div>
        <div class="panel">Panel 3</div>
        <div class="panel">Panel 4</div>
    </div>
</section>

<div class="spacer"></div>
.horizontal-scroll {
    overflow: hidden;
    height: 100vh;
}

.horizontal-container {
    display: flex;
    width: 400%; /* 100% * número de paneles */
    height: 100%;
}

.panel {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2rem;
}

.panel:nth-child(1) { background-color: #3498db; }
.panel:nth-child(2) { background-color: #2ecc71; }
.panel:nth-child(3) { background-color: #e74c3c; }
.panel:nth-child(4) { background-color: #9b59b6; }
// Scroll horizontal
gsap.to(".horizontal-container", {
    scrollTrigger: {
        trigger: ".horizontal-scroll",
        start: "top top",
        end: "+=3000", // Distancia de scroll
        pin: true,
        scrub: 1,
    },
    x: () => -(document.querySelector(".horizontal-container").offsetWidth - window.innerWidth),
    ease: "none"
});

Esto crea una sección que se desplaza horizontalmente mientras el usuario hace scroll verticalmente.

Consejos de Optimización de Rendimiento

Las animaciones ScrollTrigger pueden impactar el rendimiento si no se implementan cuidadosamente. Aquí tienes algunos consejos:

  1. Usa will-change con moderación: Solo aplícalo a elementos que realmente se animan
  2. Evita animar propiedades de layout: Mantente con transform y opacity cuando sea posible
  3. Agrupa animaciones similares: Usa gsap.utils.toArray() y recorre los elementos
  4. Elimina ScrollTriggers cuando no se necesiten: Usa scrollTrigger.kill() para aplicaciones de una sola página
  5. Reduce el uso de marcadores: Elimina markers: true en producción

Solución de Problemas Comunes

La Animación Comienza Muy Temprano/Tarde

Si tu animación se activa en momentos inesperados, verifica tus valores de start y end. Usa markers: true para visualizar los puntos de activación.

Animaciones Entrecortadas

Para animaciones más suaves, usa scrub: 0.5 o mayor en lugar de scrub: true para agregar un ligero retraso.

Problemas de Compatibilidad Móvil

Los navegadores móviles manejan los eventos de scroll de manera diferente. Prueba exhaustivamente en dispositivos móviles y considera usar ScrollTrigger.matchMedia() para crear diferentes animaciones para diferentes tamaños de pantalla.

Conclusión

Con estas técnicas, puedes crear animaciones de scroll que responden naturalmente a la interacción del usuario, mejorando tu UI sin abrumar a los usuarios. Comienza con efectos simples e incorpora gradualmente técnicas más avanzadas a medida que te sientas cómodo con las capacidades de ScrollTrigger.

Preguntas Frecuentes

Sí, pero necesitas configurar y limpiar adecuadamente las instancias de ScrollTrigger cuando los componentes se montan/desmontan.

ScrollTrigger está diseñado para GSAP, pero puedes usar sus funciones de callback para activar otras librerías.

Usa porcentajes para el posicionamiento, y actualiza ScrollTrigger en el redimensionamiento de ventana con ScrollTrigger.refresh().

La funcionalidad básica es gratuita, pero algunas características avanzadas requieren una membresía GreenSock Club.

Usa markers: true para visualizar los puntos de activación y console.log en las funciones de callback para rastrear el progreso.

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers