I am using nextjs and styled-components and I want to animate, using gsap, a navbar when the user is on mobile so that when the user clicks on the menu icon, the navbar comes out from the left, and he clicks on the cross icon, it goes out to the left.
This is the nav.js file, parent component (a child of another that just groups it into a styled header):
function Navigation (props){
const node = useRef(null);
const [open, setOpen] = useState(false);
const toggleNavbar = ()=>{
setOpen(!open)
}
useEffect(()=>{
let tween = gsap.to(node.current, {opacity: 1, left: "0%", duration: 0.5, ease:"power4.out"});
tween.play();
// This thing below doesnt work
// return function cleanup(){
// tween.reverse()
// }
});
// For media breakpoint
const _md = `${(parseInt(md) - 1)}px`
const isMobile = useMediaQuery({
query: `(max-device-width: ${_md})`
});
return(
<Nav>
{
isMobile &&
<Menu onClick={toggleNavbar}>
<MenuIcon/>
</Menu>
}
<Logo>LOGO</Logo>
{
isMobile &&
<Phone>
<div className="icon">
<PhoneIcon />
</div>
<span>+555-555-555</span>
</Phone>
}
{
isMobile &&
open &&
<NavigationList id="mobileNavList" animate={node} isOpen={open} toggleNavbar={toggleNavbar} isMobile={isMobile} />
}
{
!isMobile &&
<NavigationList isMobile={isMobile} />
}
</Nav>
);
}
The NavigationList component (navlist.js):
function NavigationList (props){
return(
<NavList ref={props.animate} isMobile={props.isMobile}>
{
props.isMobile &&
<React.Fragment>
<CrossIcon onClick={props.toggleNavbar} className="cross-icon"/>
<NavLink>HOME</NavLink>
<NavLink>MENU</NavLink>
<NavLink>CONTACT US</NavLink>
<div className="info">
<NavLink>
<NavLinkInfo>
<div className="icon phone-icon">
<PhoneIcon />
</div>
<span>+555-555-555</span>
</NavLinkInfo>
</NavLink>
<NavLink>
<NavLinkInfo>
<div className="icon location-icon">
<LocationIcon />
</div>
<span>8 Street, City, 99004</span>
</NavLinkInfo>
</NavLink>
</div>
</React.Fragment>
}
{
!props.isMobile &&
<React.Fragment>
<NavLink>HOME</NavLink>
<NavLink>MENU</NavLink>
<NavLink>CONTACT US</NavLink>
<OrderButton>
<BagIcon />
2
</OrderButton>
</React.Fragment>
}
</NavList>
);
}
I've tried to return a function in useEffect to reverse tween but the node ref turns to null before it executes. The component gets destroyed before the reverse animation takes place.
I also tried to use a promise in toggleNavbar function to tween it before updating the state. It doesn't work
How can I reverse the animation and then unmount the component with gsap?