GSAP ScrollTrigger | Toggle Actions

GSAP ScrollTrigger Toggle Actions

Introduction

In this article on GSAP's ScrollTrigger, we'll learn about toggleActions.

toggleActions give us fine-grained control over our animations when it comes to playing, pausing, restarting, etc.


We'll start with this initial HTML setup for our example's index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="div1"></div>
    <div class="div2">
      <div class="square"></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/
gsap/3.11.3/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/
gsap/3.11.3/ScrollTrigger.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>

And this will be our initial CSS for the style.css file:

body {
  margin: 0;
}

.div1,
.div2 {
  height: 100vh;
}

.div1 {
  background-color: pink;
}

.div2 {
  background-color: salmon;
}
.square {
  width: 150px;
  height: 20vh;
  background-color: fuchsia;
}
.red {
  background-color: red;
}
scrolltrigger markers

Using toggleActions

Our initial app.js file will look like this:

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});

In the browser, we can see our markers: start, end, scroller-start, and scroller-end. These will help us visualize the way that toggleActions work.

Also, notice that, at the moment, the square only animates a single time. i.e. when the top of the trigger element meets the scroller-start. markers.gif

square defaults to animating only once


So, to use toggleActions, let's add a toggleActions property to the scrollTrigger object in app.js.

The value of toggleActions will be a string of keywords. (We'll use an empty string as a placeholder for now.)

These keywords represent the actions triggered by the events.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});

The possible keywords are:

  • play
  • pause
  • resume
  • reverse
  • restart
  • reset
  • complete
  • none

We can use none when we don't want an action triggered on an event.


The four possible events are:

  • onEnter
  • onLeave
  • onEnterBack
  • onLeaveBack

(By the way, you can mix and match these actions with any event).

onEnter

Let's experiment with some toggleActions keywords now.

In this example, "play none none none" correspond to the onEnter, onLeave, onEnterBack, and onLeaveBack events.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "play none none none",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});

At the moment, our animation plays only once: the first time the top of the trigger element meets 60% down from the top of the viewport. This corresponds to the onEnter event.

However, let's have the animation restart each time the trigger element reaches that 60% point.

To do this, we'll replace the play keyword with the restart keyword:

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart none none none",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});
square animation restarts on enter

onLeave

Let's experiment with the onLeave event and use the reverse keyword.

When the trigger element leaves the scroller zone, the animation will now reverse. (Note: the scroller-start marker corresponds to onEnter. The scroller-end marker corresponds to onLeave).

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart reverse none none",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});
square animation reverses on leave


Another keyword we can try for onLeave is pause.

As you might guess, this will pause the animation once the trigger element hits the scroller-end.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart pause none none",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});
square animation pauses on leave

onEnterBack

Let's experiment with the onEnterBack event and use the resume keyword.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart pause resume none",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});

Now, notice that the animation continues(resumes) from where it left off once we re-enter the scroller zone.

square animation resumes when it re-enters scroller zone

onLeaveBack

For the onLeaveBack event, let's try the reset keyword.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart pause resume reset",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});

When the trigger element returns past the scroller-start, the square resets to the left side of the viewport.

square resets to left side of viewport

Finally, let's try using the complete keyword for the onLeaveBack event.

gsap.registerPlugin(ScrollTrigger);

gsap.to(".square", {
  x: 700,
  duration: 3,
  scrollTrigger: {
    trigger: ".square",
    start: "top 60%",
    end: "top 40%",
    toggleActions: "restart pause resume complete",
    markers: {
      startColor: "purple",
      endColor: "fuchsia",
      fontSize: "3rem",
    },
  },
});
square animation completes when trigger element reaches scroller-start

As you can see, when the trigger element meets the scroller-start once again, the box jumps to its completion.


If you're more of a visual learner, check out the video version of this article:

gsap scrolltrigger toggle actions video