Jump to content
Search Community

React on Open and on close Animation does not seem to work and im lost :)

cdawe test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Essentially, I'm trying to have a component hide and show on click, which is pretty standard in react but I was using the state (isOpen) simply like this {isOpen && <ProjectCard/> } to open and close but if I want to animate the Project card in any way it all goes to hell. I have understood that the isOpen + ternary block any kinda div or ref I wanna pass to ProjectCard. I've been able to have it open with ease in but not close, and I'm a little discouraged at the moment.
Any insight will be welcomed. there's not lots of info online and chat gpt well doesn't help either haha 

here is my code 

 

import { useState, useEffect } from "react";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";
import { useRef } from "react";

export const Tabs = () => {
  const tabs = useRef();

  const [isOpen, setIsOpen] = useState(false);

  const openPdfInNewTab = () => {
    const pdfUrl = "src/assets/Resume.pdf";
    window.open(pdfUrl, "_blank");
  };

  const handleClick = () => {
    if (isOpen) {
      gsap.to(".projects", {
        y: "100%",
        duration: 1,
        ease: "power1.inOut",
        // onComplete: () => {
        //   // Set display to 'none' when the closing animation is complete
        //   document.querySelector(".project-card").style.display = "none";
        // },
      });
      console.log("here");
      setIsOpen(false);
    } else {
      gsap.fromTo(
        ".projects",
        { y: "150%" },
        { y: "0%", duration: 1, ease: "power1.inOut" }
      );
      setIsOpen(true);
    }
  };

  // animation on load
  useGSAP(
    () => {
      gsap.from(".tab", {
        x: 150,
        ease: "power1.inOut",
        delay: 2.5,
      });
    },
    { scope: tabs }
  );

  useGSAP(
    () => {
      gsap.utils.toArray(".tab").forEach((tab) => {
        const initialWidth = tab.classList.contains("project-tab")
          ? "80px"
          : "100px";
        const hoverWidth = tab.classList.contains("project-tab")
          ? "100px"
          : "120px";

        gsap.set(tab, { width: initialWidth, textAlign: "left" });

        tab.addEventListener("mouseenter", () => {
          gsap.to(tab, { width: hoverWidth });
        });

        tab.addEventListener("mouseleave", () => {
          gsap.to(tab, { width: initialWidth });
        });
      });
    },
    { scope: tabs }
  );

  const handleEscape = (event) => {
    if (event.key === "Escape") {
      setIsOpen(false);
    }
  };

  // const handleOutsideClick = (event) => {
  //   const projectsContainer = document.querySelector(".projects");

  //   if (projectsContainer && !projectsContainer.contains(event.target)) {
  //     setIsOpen(false);
  //   }
  // };

  useEffect(() => {
    document.addEventListener("keydown", handleEscape);
    // document.addEventListener("mousedown", handleOutsideClick);

    return () => {
      document.removeEventListener("keydown", handleEscape);
      // document.removeEventListener("mousedown", handleOutsideClick);
    };
  }, []);

  return (
    <div ref={tabs} className="tabs-container">
      <div className="tab project-tab" onClick={handleClick}>
        Projects
      </div>
      <div className="tab resume-tab" onClick={openPdfInNewTab}>
        Resume
      </div>

      <div className={`projects ${isOpen ? "open" : ""}`}>
        {/* <div className="project-card"> */}
        <h1>Projects</h1>
        <ul>
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
        </ul>
        {/* </div> */}
      </div>
    </div>
  );
};

 

I was testing lots of stuff. so I have lots of weirdness, but essentially I also have animations on the tabs ( which work with no problem)

What I'm trying to achieve is basically a react/gsap problem is using the gsap hook to create and ease in and easeout when I click to show the projects, I've ultimately extracted the content of my ProjectCard component to test things, eventually ill add it back to the div. but i would also like it to ease out on the outside click and on the escape key . the outside click was causing me so much trouble because it counts the tab click also as an outside click and it would just glitch open and close 

i also made my css apply on isOpen, ive tested so many things at this point. ANY INSIGHTS WILL HELP 

thank you and if more details need to be added let me know 

Link to comment
Share on other sites

It's very difficult to troubleshoot without a minimal demo; the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Link to comment
Share on other sites

 ok so  I modified the code and it does what I want on click when I click the tab, and when I click outside or escape, so the functionality works 

but when I load the page the animation loads in and I want the "project card" to only show on click 

 

https://stackblitz.com/edit/gsap-react-basic-f48716-icctuq?file=src%2Findex.js

 

this is react so I did a stackblitz , very basic, but if you load it you see it just comes in first, and then the tabs appear and then we you click on the first tab ( on your right) it does what it should 

 

i dont know how to fix the bug on loading of the page , ive included my css.  i dont know if its a gsap issue like im not using it correctly with react or is it a me issue haha , let me know  

Link to comment
Share on other sites

i found the solution and updated my pen !  :)  if somone ever runs into this issue, i hid my component with css and added visiblity to my gsap animation + an onComplete if not open to reset the visibility to hidden!!! 

 

if anyone has other suggestions let me know 

Link to comment
Share on other sites

  • Solution

Hi,

 

You have a fundamental issue in your code here:

useGSAP(() => {
  console.log(isOpen);
  if (isOpen) {
    gsap.fromTo(
      '.project-card',
      { y: '100%' },
      { y: '0%', duration: 1, ease: 'power1.inOut', visibility: 'visible' }
    );
  } else {
    gsap.fromTo(
      '.project-card',
      { y: '0%' },
      {
        y: '100%',
        duration: 1,
        ease: 'power1.inOut',
        onComplete: () => {
          gsap.set('.project-card', { visibility: 'hidden' });
        },
      }
    );
  }
}, [isOpen]);

In GSAP from and fromTo instances take the element from the value you're passing to the configuration to the element's natural position. Also in this cases is better to just toggle a single GSAP from instance, since the natural position of the element is visible. Finally is better to animate the yPercent property instead of using y: "100%" in your animations.

 

Here is a fork of your demo:

https://stackblitz.com/edit/gsap-react-basic-f48716-g79fb9?file=src%2FProject.js

 

Hopefully this helps.
Happy Tweening!

Link to comment
Share on other sites

Hi,

 

As far as I can tell there are no courses for GSAP in React. Honestly I think there is not a lot of difference between learning GSAP in a Vanilla JS environment and React. A GSAP animation is the same regardless of the environment you're working on, since GSAP is 100% framework agnostic.

 

Resources to learn React there are quite a few, both free and paid. I'd recommend you Brad Traversy since I think his way of teaching is very straight forward and He focus on the basic stuff. Also you have the resources by Freecodecamp in Youtube:

https://www.youtube.com/@freecodecamp/search?query=react

 

For learning GSAP I strongly recommend @Carl's courses. He has over 10 years of experience with GSAP and teaching here in the forums:

https://www.creativecodingclub.com/bundles/creative-coding-club?ref=44f484

 

Hopefully this helps.

Happy Tweening!

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