I'm trying to understand this piece: https://codepen.io/GreenSock/pen/RwVgEgZ
The hard thing for me is to understand the select
property. AFAIK, this is a property of a <select>
HTML element, that it is no present in this HTML. And a particular use of forEach
.
This is the JS as I understand:
// toArray GSAP tool
// https://greensock.com/docs/v3/GSAP/UtilityMethods/toArray()
// Store an array with .accordion-group elements
let groups = gsap.utils.toArray(".accordion-group");
// Store an array with .accordion-menu elements
let menus = gsap.utils.toArray(".accordion-menu");
// Apply createAnimation(element) for each array element
// This creates animations for each .accordion-group
// and store it in a variable
let animations = groups.map(createAnimation);
// Add click event listener to each .accordion-menu
// that fires playAnimation(selected) on click
menus.forEach(menu => {
menu.addEventListener("click", () => playAnimation(menu));
});
//
function playAnimation(selected) {
// I don't undestand this particular use of forEach
// what means animate => animate(selected)?
// what means selected? I search this property on MDN web docs with no luck
animations.forEach(animate => animate(selected))
}
// CreateAnimation function
function createAnimation(element) {
// Create colections of .accordion-menu and .accordion-content
let menu = element.querySelector(".accordion-menu");
let box = element.querySelector(".accordion-content");
// GSAP initial set height of .accordion-content to auto
gsap.set(box, { height: "auto"})
// GSAP tween reversed. I have no problem with this
let tween = gsap.from(box, {
height: 0,
duration: 0.5,
ease: "power1.inOut"
}).reverse();
// CreateAnimation() returns the tween reversed if it is not selected
return function(selected) {
// Ternary operator.
// Store true in the reverse variable if menu is not selected
// Get !tween.reversed() (This means true if tween is not reversed or false if it is reversed) and store it in reversed variable.
let reversed = selected !== menu ? true : !tween.reversed();
// return tween reversed or not reversed regarding reversed variable
tween.reversed(reversed);
}
}
In short, what I want to know is: what does this mean: animate => animate(selected)
? What means selected
? I searched this property on MDN web docs with no luck.
While chliang is not wrong, I feel like explaining the process of what's going on in general is valuable as I think your understanding is not quite correct.
Here's the steps of what happens when the JS is ran:
The DOM elements are selected.
The groups are looped through and an animation for each group that animates the height of that specific group is created. This animation will be re-used each time that the group is animated (i.e. a new animation will not be created, only the state of this animation will be changed — this is a good technique of animating efficiently).
With that being said, what is actually returned is not a reference to the animation itself but rather a function that controls the reversed state of the animation. It'd probably help to look at the .reversed() documentation.
The menu items are looped through, adding a click event listener to each. The event listener for each menu item passes in that menu item to the function that was returned in the last step. Inside of the function (returned from the last step), if the menu item is the same as the one that is clicked, the reversed state for that animation is set to the opposite of what it currently is, usually being set to true
, meaning the animation will play forwards. However if it's the same one that's clicked and it's reversed state is already false
this means that it's already opened or opening, so its reversed state will be changed false
.
For all other animations, the reversed state will be set to true
, meaning it will play backwards if its progress is not 0. It will do nothing if its progress is 0.
To be clear, the HTML <select>
element is not being used and is unrelated to the demo. It achieves similar behavior but cannot be customized to behave like this accordion.
With all of that being said, I probably would have written this code in a different way to be more readable, like this.
Let me know if you have any more questions.