GSAP ScrollTrigger

ScrollTrigger is a GSAP plugin that lets you animate elements based on the user's scroll position.

What is ScrollTrigger?

Normally animations run automatically:

gsap.to(".box", {
  x: 300,
  duration: 2
});

With ScrollTrigger, animations start when the user scrolls to a specific point.

gsap.to(".box", {
  x: 300,
  scrollTrigger: ".box"
});


Install ScrollTrigger

CDN

<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/ScrollTrigger.min.js"></script>

Register Plugin

gsap.registerPlugin(ScrollTrigger);


1. Trigger

The trigger is the element that starts the animation.

Basic Syntax

gsap.to(".box", {
  x: 300,

  scrollTrigger: {
    trigger: ".box"
  }
});

Flow

User Scrolls
      ↓
Trigger Reaches Viewport
      ↓
Animation Starts

Example

<section class="section">
  <div class="box"></div>
</section>


gsap.to(".box", {
  rotation: 360,

  scrollTrigger: {
    trigger: ".section"
  }
});

Animation starts when .section enters viewport.


2. Start & End

Control exactly when animation starts and stops.

Start

start: "top center"

Meaning:

Element Top
      ↓
Viewport Center

Animation starts when element's top reaches viewport center.

Syntax

start: "elementPosition viewportPosition"



Example

scrollTrigger: {
  trigger: ".box",
  start: "top 80%"
}

Start when box reaches 80% of viewport.

End

end: "bottom center"

Animation ends when:

Element Bottom
      ↓
Viewport Center

Example

scrollTrigger: {
  trigger: ".box",
  start: "top center",
  end: "bottom center"
}


3. Scrub

Scrub links animation progress directly to scrolling.

Without scrub:

gsap.to(".box", {
  x: 500,

  scrollTrigger: {
    trigger: ".box"
  }
});

Animation plays once triggered.

With scrub:

gsap.to(".box", {
  x: 500,

  scrollTrigger: {
    trigger: ".box",
    scrub: true
  }
});

Animation follows scrollbar.

Visual

Scroll 20% → Animation 20%

Scroll 50% → Animation 50%

Scroll 100% → Animation 100%

Smooth Scrub

scrub: 2

Meaning:

Animation catches up smoothly over 2 seconds.

scrollTrigger: {
  trigger: ".box",
  scrub: 2
}