Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Aitor

Accordion with different ease when open and close

Go to solution Solved by GreenSock,

Recommended Posts

Starting from

See the Pen gOWGKQZ?editors=0110 by ZachSaucier (@ZachSaucier) on CodePen

I want to achieve an accordion with different ease when open and close. So, It relies in progress() state instead reversed() state and has two tweens (open and close) instead one tween (reversed or not). It works, more or less. The main problem is that I can't close all the .accordion-groups as in the original:

 

Original codepen (line 16):

animations.forEach(animation => animation.reverse());

 

My codepen (line 24):

animationsClose.forEach(animationClose => animationClose.play());

I can't see why.

 

See the Pen QWvOypO?editors=1010 by aitormendez (@aitormendez) on CodePen

Link to comment
Share on other sites

  • Solution

It's because that timeline's playhead is already at the end when you call .play() so there's nowhere for the playhead to go in the forward direction. It's a logic issue. 

 

I'm also not a fan of this approach where you set up the open and close animations ahead of time because:

  • It won't allow things to be dynamic and fluid. For example, what if a user clicks quickly so that when the "open" animation is halfway through, you call the "close" animation? If all the starting/ending values are pre-recorded, you'd see a sudden jump to the open state and then the animation would continue to the closed state. I much prefer that things be dynamic and smooth. 
  • You'll likely run into logic problems. Remember, animations record the starting/ending values the first time they render so that interpolation can be super-fast and to ensure repeats are true repeats. So in the scenario above, when the user clicks halfway-through the first time, it'd mess up your initial/starting values on the close animation. From that point on, it'd always close from the halfway point. 

Here's how I'd do it: 

See the Pen ZEKvzgb?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Now it's all dynamic. Click as fast as you want and it'll adjust smoothly. And each menu has a simple/intuitive open() and close() method. 

 

Does that help? 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, GreenSock said:

Does that help? 

 

Of course it helps. I agree that it is much better approach: better functionallity and more readable. After seeing this solution it seem obvious. I learned some interesting things like overwrite property. And some javascript basics: I thought this way of declaring the isOpen variable would put it in the global scope, but the variable belongs to the scope of each menu, just like box and items. Thank you much.

Link to comment
Share on other sites

There is something I don't understand.
 

let openMenu; // <------------------------- in the global scope

  menu.open = () => {
    if (!isOpen) { // <-------------------- If this menu is closed
      isOpen = true; // <------------------ set it to open
      openMenu && openMenu.close(); // <--- I don't understand this line. The last part closes
                                    //      the open menu but what does "openMenu &&" do?
      openMenu = menu; // <---------------- Store this menu in the openMenu variable
    }
  }

 

Link to comment
Share on other sites

Since we want to only allow one menu to be open at a time, we create a globally-scoped openMenu variable to store a reference to the currently open menu (if there is one). The && is just a shorter way to do some conditional logic: 

// short
openMenu && openMenu.close();

// longer
if (openMenu) {
  openMenu.close();
}

// longest
if (openMenu !== null) {
  openMenu.close();
}

Whatever is after the && only runs if the first part is truthy.

 

Without that global variable, we could loop through the menus Array and call close() on all the other ones but that seems wasteful to me and would actually require more code. 

 

Does that clear things up?

  • Like 3
Link to comment
Share on other sites

Yes! very clear. Many thanks.

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.

×