我正在使用react-fast-marquee来做水平滚动动画,并且我给它添加了缩放效果

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

我有以下代码,它按照我想要的方式工作大约 90%,它从右向左滚动,我添加了一个检查以查看图像何时到达页面中心,它应该将图像放大一点点的效果。

这对于前 3 个图像效果很好,但是当循环完成时索引 0 和索引 1 永远不会缩放。

我尝试解决这个问题有一段时间了,但似乎无法确定原因。

这是一个代码沙箱,可以查看它的运行情况并使用它

https://codesandbox.io/p/sandbox/zen-tharp-zvdwyk

任何帮助将不胜感激

    import React, { useEffect, useRef, useState } from "react";
    import Marquee from "react-fast-marquee";
    import styled from "styled-components";
    
    const props = {
      Carousel: [
        { image: "/1.webp" },
        { image: "/2.webp" },
        { image: "/3.webp" },
        { image: "/4.webp" },
        { image: "/5.webp" },
      ],
    };
    
    function Gallery() {
      const [updateLoop, setUpdateLoop] = useState(false);
    
      const [centerImageIndex, setCenterImageIndex] = useState(null);
    
      const imgRef = useRef();
    
      const [imageWidth, setImageWidth] = useState(0);
    
      function isImageHorizontallyCentered(pageWidth, imageWidth, imageX) {
        // Calculate the expected X coordinate for the image to be centered
        const expectedX = (pageWidth - imageWidth) / 2;
    
        // Define a margin of error, if necessary (e.g., for rounding)
        const marginOfError = 10; // Adjust this value based on your requirements
    
        // Check if the actual X coordinate is within the expected range
        return Math.abs(imageX - expectedX) <= marginOfError;
      }
    
      const checkImagePosition = () => {
        const pageWidth = window.innerWidth;
    
        props.Carousel.forEach((item, index) => {
          const img = document.getElementById(`image-${index}`);
    
          const imageWidth = img.getBoundingClientRect().width;
          const rect = img.getBoundingClientRect();
          const imageX = rect.left + window.scrollX;
    
          const test = isImageHorizontallyCentered(pageWidth, imageWidth, imageX);
    
          console.log("test", test, "index", index);
    
          if (test) {
            setCenterImageIndex(index);
          }
        });
      };
    
      useEffect(() => {
        const intervalId = setInterval(checkImagePosition, 100); // Check every 100ms
        return () => clearInterval(intervalId);
      }, []);
    
      return (
        <Container>
          <ImagesContainer>
            <Marquee speed={100} pauseOnHover>
              {props?.Carousel.map((listItem, index) => {
                const isCenter = index === centerImageIndex;
                return (
                  <ImageWrapper key={index} id={`image-${index}`} center={isCenter}>
                    <LazyImg ref={imgRef} loading="lazy" src={listItem.image} />
                  </ImageWrapper>
                );
              })}
            </Marquee>
          </ImagesContainer>
        </Container>
      );
    }
    
    
    const Container = styled.div`
      // width: 1200px;
      // margin: 0 auto;
      width: 100%;
    `;
    
    const Caption = styled.div`
      color: var(--Terrace-Gray-900, #282c25);
      letter-spacing: -0.32px;
      align-self: center;
      margin-top: 430px;
      white-space: nowrap;
    
      @media (max-width: 991px) {
        white-space: initial;
      }
    `;
    
    const SocialMediaText = styled.div`
      align-self: center;
      color: var(--Terrace-Neutral-Black, #000);
      text-align: center;
      letter-spacing: -2.24px;
      margin-top: 8px;
      font: 700 56px/114% Satoshi, sans-serif;
    
      @media (max-width: 991px) {
        max-width: 100%;
        font-size: 40px;
      }
    `;
    
    const ImagesContainer = styled.div`
      // border: 1px solid blue;
    `;
    
    const ImageWrapper = styled.div`
      // width: ${(props) => (props.center ? "800px" : "100px")};
      // width: 600px;
      transform: scale(${(props) => (props.center ? "1.1" : "1")});
      // border: 1px solid red;
      transition: transform 1s;
    `;
    
    const LazyImg = styled.img`
      width: 300px;
      border-radius: 50px;
      background: #e0e0e0;
      box-shadow: 20px 20px 60px #bebebe, -20px -20px 60px #ffffff;
      //write a drop shadow
    
      margin: 40px 40px;
    `;
    
    export default Gallery;

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

要解决图片卷轴中前两张图片没有变大的问题,请尝试使用

useEffect
来管理循环完成后的状态。这样,状态变化仅在图片显示完成后发生。另外,在
checkImagePosition
函数上执行“去抖”操作以减慢调用速度。这可以帮助停止快速和不必要的函数调用,使一切变得更顺利并避免出现问题。这些更改应该有助于确保状态变化与节目更好地同步,使前两张图片像其他图片一样放大。

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