Jump to content
Search Community

Toggle Animation

RC_TK test
Moderator Tag

Go to solution Solved by RC_TK,

Recommended Posts

Hi and welcome to the GreenSock forums.

 

The easiest way to toggle a GSAP instance is to toggle it's reversed state. Normally what I do is create the Tween or Timeline paused, then after adding all the config or child instances I reverse it. Since the instance is at 0 seconds there is no change. Then you toggle the reversed() state. This code seems to work in your sample:

// Timeline created and paused
var tl = gsap.timeline({ paused: true });

function openNav() {
  animateOpenNav();
  var navBtn = document.getElementById("nav");
  navBtn.onclick = function (e) {
    // Toggle reversed to it's opposite value
    tl.reversed(!tl.reversed());
    // Use the toggle method in the classList API
    navBtn.classList.toggle("active");
  };
}

function animateOpenNav() {
  var mobileNav = document.getElementById("mb_nav");
  tl.to(mobileNav, {
    duration: 1.5,
    ease: "power3.out",
    y: 0
  }).to(".nav__link", {
    opacity: 1,
    y: 0,
    duration: 3,
    stagger: {
      // wrap advanced options in an object
      each: 0.2,
      ease: "power1.in"
    }
  })
  .reverse(); // Finally reverse the timeline. reversed() is true
}

// init
openNav();

Happy Tweening!!!

  • Like 3
  • Haha 1
Link to comment
Share on other sites

  • 1 year later...

Hello everyone,

I'm trying to implement the reverse() on my React project. 

The menu appears fine. However, when I click on the menu button, the reverse doesn't seem to take in effect.

Here's my code. Thank you!

 

import React, { useState } from 'react'
import { NavLink, withRouter } from 'react-router-dom'
import { gsap } from 'gsap'

const Header = () => {
  const [isMenuOpen, setIsMenuOpen] = useState(false)

  const t1 = gsap.timeline({ paused: true })
  const openNav = () => {
    setIsMenuOpen(!isMenuOpen)
    animateOpenNav()
    t1.reversed(!t1.reversed())
  }
  const animateOpenNav = () => {
    t1.to('.navigation', {
      duration: 1.5,
      delay: 0.2,
      ease: 'expo.inOut',
      y: 0,
    }).reverse()
  }

  return (
    <div className="header">
      <div className="row v-center space-between">
        <div className="logo">
          <a href="/">
            <img src={require('../assets/logo.png')} alt="MJOY" />
          </a>
        </div>
        <div
          className={`hamburger-menu ${isMenuOpen ? 'active' : ''}`}
          onClick={openNav}
        >
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
    </div>
  )
}

export default Header
.navigation {
  left: 0;
  top: -1px;
  width: 100%;
  height: 100%;
  z-index: 3;
  position: absolute;
  overflow: hidden;
  background-color: $pink;
  padding-top: 240px;
  transform: translateY(-100%);
.header {
  position: fixed;
  width: 100%;
  height: 128px;
  z-index: 4;
  @include media('<=phone') {
    height: 96px;
  }
  .logo {
    img {
      width: 120px;
      height: auto;
      @include media('<=tablet') {
        width: 96px;
      }
    }
  }
  .hamburger-menu {
    box-sizing: border-box;
    width: 60px;
    height: 60px;
    border-radius: 100%;
    position: relative;
    background-color: $pink;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: 0.5s ease-in-out;
    &.active {
      background-color: $white;
    }
    cursor: pointer;
    @include media('<=phone') {
      width: 50px;
      height: 50px;
    }
    span {
      position: absolute;
      transition: 0.5s ease-in-out;
    }
    span:nth-child(1) {
      width: 24px;
      height: 2px;
      background: $white;
      border-radius: 4px;
      transform: translateY(-8px);
    }
    span:nth-child(2) {
      width: 24px;
      height: 2px;
      background: $white;
      border-radius: 4px;
      transform: translateY(0);
    }
    span:nth-child(3) {
      width: 24px;
      height: 2px;
      background: $white;
      border-radius: 4px;
      transform: translateY(8px);
    }
    &.active {
      span:nth-child(1) {
        transform: translateY(0);
        transform: rotate(-225deg);
        background: $pink;
      }
      span:nth-child(2) {
        opacity: 0;
        transform: translateY(0);
        transform: rotate(-225deg);
        background: $pink;
      }
      span:nth-child(3) {
        transform: translateY(0);
        transform: rotate(-315deg);
        background: $pink;
      }
    }
  }
}

 

Link to comment
Share on other sites

I just applied code like this and seems to work..

const Header = () => {
  const [isMenuOpen, setIsMenuOpen] = useState(false)

  const t1 = gsap.timeline({ paused: true })
  const openNav = () => {
    setIsMenuOpen(!isMenuOpen)
    animateOpenNav()
    t1.reversed(!t1.reversed())
  }
  const closeNav = () => {
    setIsMenuOpen(!isMenuOpen)
    animateCloseNav()
    t1.reversed(!t1.reversed())
  }
  const animateOpenNav = () => {
    t1.to('.navigation', {
      duration: 1.5,
      ease: 'expo.inOut',
      y: 0,
    }).reverse()
  }
  const animateCloseNav = () => {
    t1.to('.navigation', {
      duration: 1.8,
      delay: 0.1,
      ease: 'expo.inOut',
      y: '-100%',
    }).reverse()
  }

  return (
    <div className="header">
      <div className="row v-center space-between">
        <div className="logo">
          <a href="/">
            <img src={require('../assets/logo.png')} alt="MJOY" />
          </a>
        </div>
        <div
          className={`hamburger-menu ${isMenuOpen ? 'active' : ''}`}
          onClick={isMenuOpen ? closeNav : openNav}
        >
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
    </div>
  )
}

 

  • Thanks 1
Link to comment
Share on other sites

  • 9 months later...
On 5/27/2022 at 3:52 AM, sun9woo said:

I just applied code like this and seems to work..

I REALLY appreciate that you supplied a working follow up! I've been having issues getting GSAP and React/Nextjs to play nice and your code really helped! Between your code and the other posts on here from the awesome people, I finally have a very bad looking but functional animation!

Thank you, bro!

  • 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...