How to create GSAP animations with a reverse

How to create GSAP animations with a reverse

A beginner-oriented quick guide on how to make use of reversing GSAP animations

🔓 What you'll get from this 5-minute read

  • You'll get a better understanding of how to handle small animations with GSAP.

  • You'll be provided an example which will help you understand how to reverse an animation.

In order to see the following explanation in action, please see this codepen

🏃 Starting right away

Since I want to get directly to the example I created, I won't talk much about the The GreenSock Animation Platform (GSAP) in general. However, feel free to check out their website in order to get some more information of that sort. Therefore, I'm assuming that you know what GSAP is as you continue reading this quick guide.

For my example, I'm using the CDN in order to implement GSAP in my codepen:

https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js

🔧 Building the foundation with HTML and CSS

Consider the following HTML and CSS code in order to get our foundation done for this example:

<div class="container">
  <div class="box">idx = 0</div>
  <div class="box">idx = 1</div>
  <div class="box">idx = 2</div>
</div>
.container {
  display: flex;
  width: 100%;
  height: 100vh;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 75px;
  height: 50px;
  background-Color: black;
  border-radius: 5px;
  transition: all 0.25s;
  margin-bottom: 25px;
  color: white;
  cursor: pointer;
}
.box:hover {
  opacity: 0.8;
}

For both HTML and CSS there's not much to explain since it's pretty basic stuff. Have in mind that you can basically do whatever you want with your CSS in this case. That's just the example I picked for no specific stylistic reasons.

🎇 Using GSAP in conjunction with JavaScript

In the following, I will go step by step through my JavaScript code in order to leave some comments for better clarification.

Firstly, I used a utility method of GSAP which is named toArray(). As the name lets the reader assume, it's responsible for creating an array from pretty much everything you would want to use animations on. In this case, I'm using this utility method to make an array out of the three div elements with the respective classname of box. With this step, it gets easier to handle the elements for the following approaches.

gsapArray = gsap.utils.toArray(".box");

As a next step, I want to reach out to every single element in this gsapArray. This can be done with a forEach loop. Have in mind that the parameters ele and idx stand for the respective elements of the array with their corresponding array index.

Within this loop, I'm making use of the timeline principle by GSAP. A timeline is helpful when you are trying to achieve better control mechanisms over multiple animations. However, you can also use a timeline if you just have one animation to play through:

gsapArray.forEach((ele, idx) => {
const timeline = gsap.timeline({ paused: true, reversed: true });

timeline.to(ele, {
      width: '400px',
      duration: 1,
      ease: "circ.inOut",
      delay: idx * 1,
  });

Therefore, you can see that I'm defining a variable timeline and initializing it with a gsap.timeline function which accepts an object as a parameter. In this case, I'm setting up the timeline with reversed: true - this is actually important for the next steps in this specific example. The paused: true is needed so the animation doesn't just start on the initial loading of the code.

After the initialization, I'm adding the actual animation to the timeline, which will count for each element within this array loop (for all three div elements). The timeline.to is pretty much the same as gsap.to in this example, which is what we would use to create a single specific animation without using a timeline.

The advantage of the timeline would be that you could actually chain multiple animations in the same way with timeline.to. In a standard case, each newly created animation sequence will then be invoked as soon as the previous animation sequence is completed.

In my example, I'm adding some animation information of width, duration, ease and delay. You can check out the GSAP documentation to find different predefined eases. Besides that, I'm using a delay which will increase as the index in the array we are looping through increases. So the animation for the first element will start right away, while the last element in the array will have a delay of 2 seconds. In this case, we have an array with a length of 3 (remember that the index starts counting at 0).

For the last step, I'm adding an EventListener - also within the same forEach loop from before - which will help to start the animation for each element with a click on the div elements themselves:

  ele.addEventListener('click', function () {
        if (timeline.reversed()) {
            timeline.play();
        } 
        else {
            timeline.reverse();
        }
  })
});

This right here is actually the exciting part, since this logic is the reason why we can reverse the animation on a click.

Therefore, we are checking if the timeline from above is currently reversed with if (timeline.reversed()) - this is why we had to put reverse: true at the initialization of our timeline. Due to this approach, the timeline gets played on the first click.

If we hadn't put reversed: true, the first click would have had no effect in this case. When timeline.reversed() is false, we go into the else part and see that the animation will get reversed with reverse() - don't get confused by the spelling, there is reversed() for boolean checking as well as reverse() to actually make the change.

And that's it! You are now able to create similar animations where you have full control of playing an animaton forwards or backwards (bringing it back to its original state).

✅ Conclusion

After considering the given example, you are now easily able to work with smaller GSAP animations which should snap back to their original position after they are invoked initially. You also got a small hands-on example for using timelines in GSAP while you got to know the toArray() utility method.