Search code examples
javascriptnext.jsgsap

How to pause/start GSAP animation in onClick event Nextjs


I want to pause/start animation using GSAP in Nextjs. I can't find a way to work with a tl.current outside the useEffect hook. This in this component when I click on the first .imgWrapper I want the tl.current to toggle tl.current.paused(true) and pause the animation. But no way I can make it work

export const Projects = () => {
  const projects = useRef();
  const projectTitle = useRef(null);
  const tl = useRef();
  const q = gsap.utils.selector(projects);

  useEffect(() => {
    tl.current = gsap
      .timeline()
      .from(q(".singleProject:nth-child(2)"), {
        y: 2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        paused: false,
      })
      .to(q(".singleProject:nth-child(2)"), {
        y: -2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        paused: false,
      });
    tl.current = gsap
      .timeline()
      .from(q(".singleProject:nth-child(3)"), {
        y: 2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        delay: 1,
      })
      .to(q(".singleProject:nth-child(3)"), {
        y: -2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        delay: 1,
      });
    tl.current = gsap
      .timeline()
      .from(q(".singleProject:nth-child(4)"), {
        y: 2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        delay: 2,
      })
      .to(q(".singleProject:nth-child(4)"), {
        y: -2000,
        ease: Linear.easeNone,
        opacity: 1,
        duration: 20,
        repeat: -1,
        delay: 2,
      });
   
  }, []);
  const [animate_1, setAnimate_1] = useState(false);
  const [animate_2, setAnimate_2] = useState(false);
  const [animate_3, setAnimate_3] = useState(false);

  return (
    <section
      ref={projects}
      id="projects"
      className={`${animate_1 && "animated_1"} ${animate_2 && "animated_2"} ${
        animate_3 && "animated_3"
      }
       w_100 h_100vh flex flexColumn flexAlignCenter flexCenter p4em`}
    >
      <div className="projectsLoading flex flexCenter flexAlignCenter w_100 h_100">
        <h2>LOADING PROJECTS</h2>
      </div>
      <div className={`singleProject w_100 flex flexStart`}>
        <div className="imgWrapper" onClick={() => some code}>
          <img src={"https://www.aimanalmureish.com/img/lego.jpg"} />
        </div>
      </div>
      <div className="singleProject w_100 flex flexEnd">
        <div className="imgWrapper">
          <img
            onClick={() => {
              setAnimate_2(!animate_2);
            }}
            src={"https://www.aimanalmureish.com/img/jordan.png"}
          />
        </div>
      </div>
      <div className="singleProject w_100 flex flexStart">
        <div className="imgWrapper">
          <img
            onClick={() => setAnimate_3(!animate_3)}
            src={"https://www.aimanalmureish.com/img/ferrari.png"}
          />
        </div>
      </div>
    </section>
  );
};

This is what is showing up in the console when I colsole.log(tl.current.pause())

https://i.sstatic.net/xo0LR.png

Thanks for the help


Solution

  • This is the updated answer to the question.

    export const Projects = () => {
      const projects = useRef();
      const projectTitle = useRef(null);
      const tl = useRef();
      const first = useRef();
      const second = useRef();
      const third = useRef();
      const q = gsap.utils.selector(projects);
    
      useEffect(() => {
        first.current = gsap
          .timeline()
          .from(q(".singleProject:nth-child(2)"), {
            y: 2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            paused: false,
          })
          .to(q(".singleProject:nth-child(2)"), {
            y: -2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            paused: false,
          });
    
        second.current = gsap
          .timeline()
          .from(q(".singleProject:nth-child(3)"), {
            y: 2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            delay: 1,
          })
          .to(q(".singleProject:nth-child(3)"), {
            y: -2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            delay: 1,
          });
        third.current = gsap
          .timeline()
          .from(q(".singleProject:nth-child(4)"), {
            y: 2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            delay: 2,
          })
          .to(q(".singleProject:nth-child(4)"), {
            y: -2000,
            ease: Linear.easeNone,
            opacity: 1,
            duration: 20,
            repeat: -1,
            delay: 2,
          });
      }, []);
      const [animate_1, setAnimate_1] = useState(false);
      const [animate_2, setAnimate_2] = useState(false);
      const [animate_3, setAnimate_3] = useState(false);
    
      return (
        <section
          ref={projects}
          id="projects"
          className={`${animate_1 && "animated_1"} ${animate_2 && "animated_2"} ${
            animate_3 && "animated_3"
          }
           w_100 h_100vh flex flexColumn flexAlignCenter flexCenter p4em`}
        >
          <div className="projectsLoading flex flexCenter flexAlignCenter w_100 h_100">
            <h2>LOADING PROJECTS</h2>
          </div>
          <div ref={first} className={`singleProject w_100 flex flexStart`}>
            <div
              className="imgWrapper"
              onMouseEnter={() => {
                first.current.paused(true);
                second.current.paused(true);
                third.current.paused(true);
              }}
              onMouseLeave={() => {
                first.current.paused(false);
                second.current.paused(false);
                third.current.paused(false);
              }}
            >
              <img src={"https://www.aimanalmureish.com/img/lego.jpg"} />
            </div>
            {/* <div className="projectDetails flex flexColumn flexAlignStart flexCenter">
              <h2 ref={projectTitle}>PROJECT TITLE</h2>
              <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem,
                veniam! Reiciendis, totam explicabo quisquam dolorem quibusdam sit
                dignissimos corporis veniam.
              </p>
            </div> */}
          </div>
          <div ref={second} className="singleProject w_100 flex flexEnd">
            <div className="imgWrapper">
              <img
                onMouseEnter={() => {
                  first.current.paused(true);
                  second.current.paused(true);
                  third.current.paused(true);
                }}
                onMouseLeave={() => {
                  first.current.paused(false);
                  second.current.paused(false);
                  third.current.paused(false);
                }}
                src={"https://www.aimanalmureish.com/img/jordan.png"}
              />
            </div>
    
            {/* <div className="projectDetails flex flexColumn flexAlignStart flexCenter">
              <h2 ref={projectTitle}>PROJECT TITLE</h2>
              <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem,
                veniam! Reiciendis, totam explicabo quisquam dolorem quibusdam sit
                dignissimos corporis veniam.
              </p>
            </div> */}
          </div>
          <div ref={third} className="singleProject w_100 flex flexStart">
            <div className="imgWrapper">
              <img
                onMouseEnter={() => {
                  first.current.paused(true);
                  second.current.paused(true);
                  third.current.paused(true);
                }}
                onMouseLeave={() => {
                  first.current.paused(false);
                  second.current.paused(false);
                  third.current.paused(false);
                }}
                src={"https://www.aimanalmureish.com/img/ferrari.png"}
              />
            </div>
          </div>
        </section>
      );
    };