Jump to content
Search Community

Toggle animation state?

iggy test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hey all,

 

I am trying to create a toggle animation state for accordions: 

When user clicks on first rectangle, the first rectangle will expand.

Then user clicks on the second one, the first would collapse and second expands. 

When user clicks on the expanded rectangle, it will collapse.

 

Similar to this codepen (except this one doesn't collapse when you click it at expanded state)

See the Pen reQMXp by valaxin (@valaxin) on CodePen

 

 

 

This is what I have. The code above uses CSS/ JS to add/remove class, but I wanted to implement it using GSAP only. I think this is doable using reverse() and play().

See the Pen QYjMpj?editors=1010 by iggyDood (@iggyDood) on CodePen

 

 

I have tried other forum posts like this one, another one and several others, but I can't get it to work. Would you guys mind guiding me to the right direction?

See the Pen QYjMpj by iggyDood (@iggyDood) on CodePen

Link to comment
Share on other sites

Welcome to the forums. 

 

Thanks for the demos. You were pretty close.

It looks like you were just using one timeline and were either reversing it or adding new tweens to the end of it.

 

One way to handle this is to

 

  1. create an animation for each element
  2.  each time you click on a new rectangle >
    1. if the currentAnimation is the same as the animation for the element you just clicked, then ONLY close that animation (reverse it)
    2. or else if the currentAnimation is for another element, close the currentAnimation, play the animation of the item you clicked, and re-assign your currentAnimation variable

it probably looks better in code:

var currentAnimation = new TimelineLite();

rectangles.forEach((el) => {
  var tl = new TimelineLite({paused:true});
   tl.to(el, 0.5, {
        width: "15rem"
      })
   el.animation = tl;
  
  el.addEventListener("click", (event) => {
   if(el.animation == currentAnimation){
     el.animation.reverse();
   } else {
     currentAnimation.reverse();
     el.animation.play();
     currentAnimation = el.animation;   
   }
   
   
  })
})

 

See the Pen LqprrP?editors=0011 by GreenSock (@GreenSock) on CodePen

 

 

  • Like 3
Link to comment
Share on other sites

Awesome! Thank you very much Carl. Appreciate the swift response.

 

I modified the code slightly because:

if the user clicks on, say the first item, the item expands

User clicks on that expanded item, and it collapses

User clicks on that same (now) collapsed item, it does nothing. 

 

I didn't specify it in the beginning, that was my bad.


Anywho, I added `.reversed()` check, and it looks like this now:
 

  el.addEventListener("click", (event) => {
   if(el.animation == currentAnimation){
     if(!el.animation.reversed()){
       el.animation.reverse();       
     } else {
       el.animation.play()
     }
   } else {

  ...

 

Now it works fantastic. Thanks for providing the building block! I didn't realize I could use .animation API!

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...