or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-plugins.mdanimation-control.mdcore-animation.mdcss-properties.mddraggable.mdindex.mdscroll-trigger.mdsvg-animation.mdtext-animation.mdtimeline-system.mdutility-functions.md
tile.json

scroll-trigger.mddocs/

ScrollTrigger

ScrollTrigger is GSAP's scroll-based animation plugin that triggers animations based on scroll position. It provides precise control over when animations start and end based on element visibility and scroll progress.

Setup

import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

Capabilities

Creating ScrollTriggers

Create scroll-based animation triggers with comprehensive configuration options.

/**
 * Create a ScrollTrigger instance
 * @param vars - ScrollTrigger configuration
 * @returns ScrollTrigger instance
 */
ScrollTrigger.create(vars: ScrollTrigger.Vars): ScrollTrigger;

interface ScrollTrigger.Vars {
  // Core properties
  trigger?: Element | string;        // Element that triggers the animation
  start?: string | number | Function; // When animation starts
  end?: string | number | Function;   // When animation ends
  
  // Animation
  animation?: gsap.core.Animation;   // Animation to control
  toggleActions?: string;            // Actions for enter/leave/enterBack/leaveBack
  
  // Callbacks
  onEnter?: Function;               // Called when entering trigger area
  onLeave?: Function;               // Called when leaving trigger area
  onEnterBack?: Function;           // Called when entering from below
  onLeaveBack?: Function;           // Called when leaving upward
  onUpdate?: Function;              // Called on scroll update
  onToggle?: Function;              // Called on any toggle
  onRefresh?: Function;             // Called when refreshed
  
  // Scrubbing
  scrub?: boolean | number;         // Link animation progress to scroll
  
  // Visual helpers
  markers?: boolean | object;       // Show visual markers for debugging
  
  // Advanced
  pin?: boolean | Element | string; // Pin element during scroll
  pinSpacing?: boolean;             // Add spacing for pinned elements
  snap?: number | object;           // Snap to specific scroll positions
  
  // Responsive
  refreshPriority?: number;         // Refresh priority order
  invalidateOnRefresh?: boolean;    // Invalidate animation on refresh
}

Usage Examples:

// Basic ScrollTrigger
ScrollTrigger.create({
  trigger: ".box",
  start: "top 80%",    // When top of .box hits 80% of viewport
  end: "bottom 20%",   // When bottom of .box hits 20% of viewport
  animation: gsap.to(".box", { x: 100, duration: 1 }),
  toggleActions: "play none none reverse"
});

// With scrubbing (animation linked to scroll progress)
ScrollTrigger.create({
  trigger: ".section",
  start: "top bottom",
  end: "bottom top",
  animation: gsap.to(".element", { rotation: 360, duration: 1 }),
  scrub: true // Animation progress matches scroll progress
});

Toggle Actions

Control animation behavior when entering/leaving the trigger area.

// Toggle actions format: "onEnter onLeave onEnterBack onLeaveBack"
type ToggleActions = string; // e.g., "play pause resume reverse"

// Available actions:
// "play" - Play the animation
// "pause" - Pause the animation
// "resume" - Resume the animation
// "reverse" - Reverse the animation
// "restart" - Restart the animation
// "reset" - Reset to beginning
// "complete" - Jump to completion
// "none" - Do nothing

Usage Examples:

ScrollTrigger.create({
  trigger: ".box",
  start: "top 50%",
  end: "bottom 50%",
  animation: gsap.to(".box", { x: 100, duration: 1 }),
  toggleActions: "play reverse play reverse" // Play on enter, reverse on leave
});

// Different behaviors for each direction
ScrollTrigger.create({
  trigger: ".element",
  animation: gsap.from(".element", { opacity: 0, y: 50, duration: 1 }),
  toggleActions: "play none none reset" // Play once, reset when scrolling back up
});

Scrubbing

Link animation progress directly to scroll position for smooth, scroll-driven animations.

interface ScrubConfig {
  scrub?: boolean | number;  // true, false, or lag amount (0.1-3)
}

Usage Examples:

// Direct scrubbing (no lag)
ScrollTrigger.create({
  trigger: ".section",
  start: "top bottom",
  end: "bottom top",
  scrub: true,
  animation: gsap.to(".parallax", { y: -200, ease: "none", duration: 1 })
});

// Smooth scrubbing with lag
ScrollTrigger.create({
  trigger: ".hero",
  start: "top bottom",
  end: "bottom top",
  scrub: 1, // 1 second of lag for smooth effect
  animation: gsap.to(".hero-bg", { scale: 1.2, ease: "none", duration: 1 })
});

Pinning

Pin elements in place during scroll for immersive scroll experiences.

interface PinConfig {
  pin?: boolean | Element | string;  // Element to pin
  pinSpacing?: boolean;              // Whether to add spacing
  pinType?: "fixed" | "transform";   // Pinning method
  anticipatePin?: number;            // Anticipate pin by this amount
}

Usage Examples:

// Pin an element
ScrollTrigger.create({
  trigger: ".panel",
  start: "top top",
  end: "+=500", // Pin for 500px of scroll
  pin: true,
  animation: gsap.to(".panel .content", { rotation: 360, duration: 1 }),
  scrub: true
});

// Pin without spacing (overlap next content)
ScrollTrigger.create({
  trigger: ".sticky-section",
  start: "top top",
  end: "bottom bottom",
  pin: ".sticky-element",
  pinSpacing: false
});

Batch Processing

Create multiple ScrollTriggers efficiently with batch processing.

/**
 * Create ScrollTriggers for multiple elements efficiently
 * @param targets - Elements to create ScrollTriggers for
 * @param vars - Configuration applied to all targets
 * @returns Array of ScrollTrigger instances
 */
ScrollTrigger.batch(
  targets: string | Element | Element[], 
  vars: ScrollTrigger.Vars
): ScrollTrigger[];

Usage Examples:

// Batch animate multiple elements
ScrollTrigger.batch(".fade-in", {
  onEnter: (elements) => gsap.from(elements, {
    opacity: 0,
    y: 50,
    duration: 1,
    stagger: 0.1
  }),
  onLeave: (elements) => gsap.to(elements, {
    opacity: 0,
    y: -50,
    duration: 0.5,
    stagger: 0.1
  }),
  onEnterBack: (elements) => gsap.to(elements, {
    opacity: 1,
    y: 0,
    duration: 1,
    stagger: 0.1
  })
});

Static Methods

Global ScrollTrigger management and utility methods.

/**
 * Refresh all ScrollTriggers (recalculate positions)
 */
ScrollTrigger.refresh(): void;

/**
 * Update all ScrollTriggers (check current scroll position)
 */
ScrollTrigger.update(): void;

/**
 * Kill all ScrollTriggers
 * @param revert - Whether to revert animations
 */
ScrollTrigger.killAll(revert?: boolean): void;

/**
 * Get all ScrollTrigger instances
 * @returns Array of all ScrollTriggers
 */
ScrollTrigger.getAll(): ScrollTrigger[];

/**
 * Get ScrollTrigger by ID
 * @param id - ScrollTrigger ID
 * @returns ScrollTrigger instance or undefined
 */
ScrollTrigger.getById(id: string): ScrollTrigger | undefined;

/**
 * Set global ScrollTrigger configuration
 * @param config - Global configuration options
 */
ScrollTrigger.config(config: {
  limitCallbacks?: boolean;
  syncInterval?: number;
  ignoreMobileResize?: boolean;
  autoRefreshEvents?: string;
}): void;

Usage Examples:

// Refresh after DOM changes
ScrollTrigger.refresh();

// Force update scroll position
ScrollTrigger.update();

// Clean up all ScrollTriggers
ScrollTrigger.killAll();

// Get all instances for debugging
const allTriggers = ScrollTrigger.getAll();
console.log(`Active ScrollTriggers: ${allTriggers.length}`);

// Global configuration
ScrollTrigger.config({
  limitCallbacks: true,    // Limit callback frequency for performance
  ignoreMobileResize: true // Don't refresh on mobile resize
});

Media Queries

Responsive ScrollTrigger management with media query support.

/**
 * Create media query-based ScrollTriggers
 * @param config - Media query configuration
 * @returns MatchMedia instance
 */
ScrollTrigger.matchMedia(config: {
  [query: string]: Function;
}): gsap.MatchMedia;

/**
 * Clear media query ScrollTriggers
 * @param query - Specific query to clear (optional)
 */
ScrollTrigger.clearMatchMedia(query?: string): void;

Usage Examples:

// Responsive ScrollTriggers
ScrollTrigger.matchMedia({
  // Desktop
  "(min-width: 768px)": function() {
    ScrollTrigger.create({
      trigger: ".desktop-element",
      start: "top 50%",
      animation: gsap.to(".desktop-element", { x: 100, duration: 1 })
    });
  },
  
  // Mobile
  "(max-width: 767px)": function() {
    ScrollTrigger.create({
      trigger: ".mobile-element", 
      start: "top 80%",
      animation: gsap.to(".mobile-element", { y: 50, duration: 1 })
    });
  }
});

// Clear mobile queries when no longer needed
ScrollTrigger.clearMatchMedia("(max-width: 767px)");

Instance Properties and Methods

Properties and methods available on ScrollTrigger instances.

interface ScrollTrigger {
  // Properties
  trigger: Element;              // Trigger element
  start: number;                // Start position in pixels
  end: number;                  // End position in pixels
  progress: number;             // Current progress (0-1)
  direction: number;            // Scroll direction (1 or -1)
  isActive: boolean;            // Whether currently active
  
  // Methods
  kill(revert?: boolean): void;     // Destroy the ScrollTrigger
  refresh(): void;                  // Recalculate positions
  update(force?: boolean): void;    // Update current state
  enable(): void;                   // Enable the ScrollTrigger
  disable(): void;                  // Disable the ScrollTrigger
  getVelocity(): number;           // Get scroll velocity
}

Usage Examples:

const st = ScrollTrigger.create({
  trigger: ".section",
  start: "top 50%",
  onUpdate: self => {
    console.log(`Progress: ${self.progress}`);
    console.log(`Direction: ${self.direction > 0 ? "down" : "up"}`);
    console.log(`Velocity: ${self.getVelocity()}`);
  }
});

// Control instance
st.disable(); // Temporarily disable
st.enable();  // Re-enable
st.refresh(); // Recalculate if layout changed
st.kill();    // Destroy when no longer needed

Position Parameters

Understanding start and end position syntax for precise trigger control.

// Position format: "trigger-position viewport-position"
// Trigger positions: "top", "center", "bottom", pixel values, percentages
// Viewport positions: "top", "center", "bottom", pixel values, percentages

type PositionString = string; // Examples:
// "top top"      - Top of trigger hits top of viewport
// "top center"   - Top of trigger hits center of viewport  
// "center 80%"   - Center of trigger hits 80% down viewport
// "bottom+=100 top" - 100px below bottom of trigger hits top of viewport

Usage Examples:

ScrollTrigger.create({
  trigger: ".element",
  start: "top 80%",        // Animation starts when top of element hits 80% of viewport
  end: "bottom 20%",       // Animation ends when bottom of element hits 20% of viewport
  animation: gsap.to(".element", { opacity: 1, duration: 1 })
});

// Using pixel offsets
ScrollTrigger.create({
  trigger: ".section",
  start: "top+=50 center", // 50px below top of section hits center of viewport
  end: "bottom-=100 top",  // 100px above bottom of section hits top of viewport
  scrub: true,
  animation: gsap.to(".bg", { y: -100, ease: "none", duration: 1 })
});