Nextjs如何pause/start onClick事件中的GSAP动画

How to pause/start GSAP animation in onClick event Nextjs

我想 pause/start 在 Nextjs 中使用 GSAP 制作动画。我找不到在 useEffect 挂钩之外使用 tl.current 的方法。在这个组件中,当我单击第一个 .imgWrapper 时,我希望 tl.current 切换 tl.current.paused(true) 并暂停动画。但是我没办法让它工作

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>
  );
};

这是我 colsole.log(tl.current.pause())

时控制台中显示的内容

https://i.stack.imgur.com/xo0LR.png

感谢您的帮助

这是问题的更新答案。

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>
  );
};