【问题标题】:Creating Parallax effect using setState使用 setState 创建视差效果
【发布时间】:2021-08-23 10:48:22
【问题描述】:

目前我想要实现的是,当用户向下滚动时,1 张图像会从左向右移动,从而产生视差效果:

通常我会使用 DOM:

let image = document.getElementById("image");

window.addEventListener('scroll', function() {
  let value = window.scrollY;
  image.style.marginRight = value * 4 + 'px';
  image.style.marginTop = value * 1.5 + 'px';
}

但目前我正在尝试使用 setState 在 React 中复制此效果,但图像不会随着鼠标滚轮移动,并且布局似乎不正确。 到目前为止,当我的滚动高度在 1 到 300 像素之间时,我已经制作了效果,此时我的图像从中心移动到左侧。但我希望它在 300px 到 600px 之后,图像应该从左向右移动,如参考图像所示。

代码沙盒:https://codesandbox.io/s/modest-hill-2wuko

当前代码:

const [leftScroll, setLeftScroll] = useState(false);
  const [topScroll, setTopScroll] = useState(false);
  const [textScroll, setTextScroll] = useState(false);

  useEffect(function onFirstMount() {
    const changeBackground = () => {
      let value = window.scrollY;
      console.log(window.scrollY);

      if (value > 0 && value < 300) {
        setLeftScroll(true);
        setTopScroll(true);
        setTextScroll(true);
      } else {
        setLeftScroll(false);
        setTopScroll(false);
        setTextScroll(false);
      }
    };

    window.addEventListener("scroll", changeBackground);

    return null;
  }, []);
  return (
    <div className="background">
      <div
        style={{
          backgroundColor: "#0E2043",
          padding: "50px",
          height: "1000px",
          display: "flex",
          justifyContent: "center"
        }}
      >
        <div className="header">Vanuatu</div>
        <img
          className="image"
          style={{
            marginRight: leftScroll ? "300px" : "0px",
            transition: "2s",
            marginTop: topScroll ? "300px" : "0px"
          }}
          alt="random"
          src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
        />
        <div
          className="text"
          style={{
            marginTop: textScroll ? "300px" : "800px",
            transition: "4s",
            marginLeft: "120px"
          }}
        >
          Minimum Investment
        </div>
      </div>
    </div>

【问题讨论】:

  • 您不需要为此使用state,实际上您不应该为此使用状态。您不想在每次滚动回调调用时重新渲染组件,即每个像素
  • @andymccullough 所以你能推荐我一个库或一些可以帮助我实现我想要的代码的代码。我基本上希望我的图像能够左右移动,从而产生视差效果以及旁边的文本移动

标签: javascript css reactjs


【解决方案1】:

就像在 cmets 中提到的 Andy 一样,您不想将 useState 用于此类动画。如果你已经有没有 React 的这个特性的代码,你也可以在你的 React 代码中使用它。除了您想使用useRef 来创建对您要设置动画的元素的引用。

另外,不要忘记在组件卸载后清理你的事件监听器。

  const imageRef = useRef();
  const textRef = useRef();

  useEffect(function onFirstMount() {
    const changeBackground = () => {
      let value = window.scrollY;

      if (value > 0 && value < 300) {
        textRef.current.style.marginTop = "300px";
        imageRef.current.style.marginRight = "300px";
        imageRef.current.style.marginTop = "300px";
      } else {
        textRef.current.style.marginTop = "800px";
        imageRef.current.style.marginRight = "0px";
        imageRef.current.style.marginTop = "0px";
      }
    };

    window.addEventListener("scroll", changeBackground);

    return () => window.removeEventListener("scroll", changeBackground);
  }, []);

  return (
    <div className="background">
      <div
        style={{
          backgroundColor: "#0E2043",
          padding: "50px",
          height: "1000px",
          display: "flex",
          justifyContent: "center"
        }}
      >
        <div className="header">Vanuatu</div>
        <img
          ref={imageRef}
          className="image"
          style={{ transition: "2s" }}
          alt="random"
          src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
        />
        <div
          ref={textRef}
          className="text"
          style={{
            transition: "4s",
            marginLeft: "120px"
          }}
        >
          Minimum Investment
        </div>
      </div>
    </div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多