使用 GSAP 在 React 中实现平滑的鼠标操作

问题描述 投票:0回答:1

我正在尝试使用 React 中的 GSAP 来实现平滑的滚动操作。 请注意,这与通常的平滑滚动不同。我试图复制的示例可以在 this 网站中看到:

这是我的尝试:

import React, { useRef, useEffect, useState } from 'react';
import { TweenLite } from 'gsap';

const Scroller = () => {
  const [scroller, setScroller] = useState({
    target: null,
    ease: 0.05,
    endY: 0,
    y: 0,
    resizeRequest: 1,
    scrollRequest: 0,
  });

  const requestRef = useRef(null);

  const onLoad = () => {
    updateScroller();
    window.focus();
    window.addEventListener("resize", onResize);
    document.addEventListener("scroll", onScroll);
  };

  const updateScroller = () => {
    const resized = scroller.resizeRequest > 0;

    if (resized) {
      const height = scroller.target.clientHeight;
      document.body.style.height = height + "px";
      setScroller(prevState => ({
        ...prevState,
        resizeRequest: 0,
      }));
    }

    const scrollY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

    setScroller(prevState => ({
      ...prevState,
      endY: scrollY,
      y: prevState.y + (scrollY - prevState.y) * prevState.ease,
    }));

    if (Math.abs(scrollY - scroller.y) < 0.05 || resized) {
      setScroller(prevState => ({
        ...prevState,
        y: scrollY,
        scrollRequest: 0,
      }));
    }

    TweenLite.set(scroller.target, {
      y: -scroller.y,
    });

    requestRef.current = scroller.scrollRequest > 0 ? requestAnimationFrame(updateScroller) : null;
  };

  const onScroll = () => {
    setScroller(prevState => ({
      ...prevState,
      scrollRequest: prevState.scrollRequest + 1,
    }));

    if (!requestRef.current) {
      requestRef.current = requestAnimationFrame(updateScroller);
    }
  };

  const onResize = () => {
    setScroller(prevState => ({
      ...prevState,
      resizeRequest: prevState.resizeRequest + 1,
    }));

    if (!requestRef.current) {
      requestRef.current = requestAnimationFrame(updateScroller);
    }
  };

  useEffect(() => {
    setScroller(prevState => ({
      ...prevState,
      target: document.querySelector("#scroll-container"),
    }));
  }, []);

  useEffect(() => {
    if (scroller.target) {
      TweenLite.set(scroller.target, {
        rotation: 0.01,
        force3D: true,
      });
    }
  }, [scroller.target]);

  useEffect(() => {
    window.addEventListener('load', onLoad);
    return () => {
      window.removeEventListener('load', onLoad);
      window.removeEventListener('resize', onResize);
      document.removeEventListener('scroll', onScroll);
      cancelAnimationFrame(requestRef.current);
    };
  }, []);

  return (
    <section className="viewport">
      <div id="scroll-container" className="scroll-container">
        <div className="content">

          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-10.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-14.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-15.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-16.jpg" alt="" />
          </div>

        </div>
      </div>
    </section>
  );
};

export default Scroller;

但是,这不起作用。没有任何错误,但滚动动作也没有区别。

请帮帮我,先谢谢了!

javascript css reactjs scroll gsap
1个回答
0
投票

要在React中使用GSAP实现平滑滚动,可以利用GSAP提供的ScrollTrigger插件。这个插件可以让您轻松创建高级的基于滚动的动画。

以下是如何使用 GSAP 修改组件以实现平滑滚动

import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

// Ensure that ScrollTrigger is added to GSAP
gsap.registerPlugin(ScrollTrigger);

const Scroller = () => {
  const scrollContainerRef = useRef(null);

  useEffect(() => {
    // Function to initialize GSAP ScrollTrigger
    const initScrollTrigger = () => {
      gsap.to(scrollContainerRef.current, {
        y: () => -(scrollContainerRef.current.clientHeight - window.innerHeight),
        ease: 'none',
        scrollTrigger: {
          trigger: scrollContainerRef.current,
          start: 'top top',
          end: () => `+=${scrollContainerRef.current.clientHeight}`,
          scrub: true,
        },
      });
    };

    // Initialize ScrollTrigger on component mount
    initScrollTrigger();

    // Cleanup function
    return () => {
      ScrollTrigger.getAll().forEach(instance => {
        instance.kill();
      });
    };
  }, []);

  return (
    <section className="viewport">
      <div ref={scrollContainerRef} className="scroll-container">
        <div className="content">
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-10.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-14.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-15.jpg" alt="" />
          </div>
          <div className="img-container">
            <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/splash-16.jpg" alt="" />
          </div>
        </div>
      </div>
    </section>
  );
};

export default Scroller;

我们使用useRef定义了一个scrollContainerRef来引用滚动容器元素。

在 useEffect 挂钩中,我们为滚动容器元素初始化 GSAP ScrollTrigger。

我们使用 gsap.to() 定义动画以根据滚动位置垂直移动滚动容器。

scrollTrigger 选项用于定义滚动行为。我们将其设置为在容器顶部到达视口顶部时开始,在容器高度滚动过去时结束。

擦洗:true 选项可实现平滑滚动。

最后,我们在组件卸载时清理 ScrollTrigger 实例。

这应该创建一种平滑的滚动效果,类似于您在 React 中使用 GSAP 的示例网站中引用的效果。

© www.soinside.com 2019 - 2024. All rights reserved.