reactjs - Logo Scroll Carousel Animation Hitching - Stack Overflow

I am trying to make a logo scroll carousel component that scrolls infinitely. The list of logos is dupl

I am trying to make a logo scroll carousel component that scrolls infinitely. The list of logos is duplicated (so it’s 200% wide) and then using a CSS animation to move it from translateX(0) to translateX(-50%). When it reaches the end, it should seamlessly repeat. Unfortunately, there is a hitch when the animation resets.

How can this be fixed?

LogoCarousel.tsx

import React from 'react';
import styles from './LogoCarousel.module.css';

interface LogoCarouselProps {
    logos: string[];
}

export const LogoCarousel: React.FC<LogoCarouselProps> = ({ logos }) => {
    return (
        <div className={styles.logoCarousel}>
            <div className={styles.logoTrack}>
                {/* First set */}
                {logos.map((logo, index) => (
                    <div className={styles.logoItem} key={`logo-1-${index}`}>
                        <img src={logo} alt={`Sponsor logo ${index + 1}`} />
                    </div>
                ))}
                {/* Second set */}
                {logos.map((logo, index) => (
                    <div className={styles.logoItem} key={`logo-2-${index}`}>
                        <img src={logo} alt={`Sponsor logo ${index + 1} (copy)`} />
                    </div>
                ))}
            </div>
        </div>
    );
};

LogoCarousel.module.css

.logoCarousel {
  position: relative;
  overflow: hidden;
  width: 100%;
  margin: 2rem auto;
}

.logoTrack {
  display: flex;
  width: 200%;
  animation: scroll 10s linear infinite;
  will-change: transform;
}

.logoItem {
  flex: 0 0 auto;
  width: 200px;
  margin-right: 2rem;
}

.logoItem img {
  width: 100%;
  height: auto;
  display: block;
}

@keyframes scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

I am trying to make a logo scroll carousel component that scrolls infinitely. The list of logos is duplicated (so it’s 200% wide) and then using a CSS animation to move it from translateX(0) to translateX(-50%). When it reaches the end, it should seamlessly repeat. Unfortunately, there is a hitch when the animation resets.

How can this be fixed?

LogoCarousel.tsx

import React from 'react';
import styles from './LogoCarousel.module.css';

interface LogoCarouselProps {
    logos: string[];
}

export const LogoCarousel: React.FC<LogoCarouselProps> = ({ logos }) => {
    return (
        <div className={styles.logoCarousel}>
            <div className={styles.logoTrack}>
                {/* First set */}
                {logos.map((logo, index) => (
                    <div className={styles.logoItem} key={`logo-1-${index}`}>
                        <img src={logo} alt={`Sponsor logo ${index + 1}`} />
                    </div>
                ))}
                {/* Second set */}
                {logos.map((logo, index) => (
                    <div className={styles.logoItem} key={`logo-2-${index}`}>
                        <img src={logo} alt={`Sponsor logo ${index + 1} (copy)`} />
                    </div>
                ))}
            </div>
        </div>
    );
};

LogoCarousel.module.css

.logoCarousel {
  position: relative;
  overflow: hidden;
  width: 100%;
  margin: 2rem auto;
}

.logoTrack {
  display: flex;
  width: 200%;
  animation: scroll 10s linear infinite;
  will-change: transform;
}

.logoItem {
  flex: 0 0 auto;
  width: 200px;
  margin-right: 2rem;
}

.logoItem img {
  width: 100%;
  height: auto;
  display: block;
}

@keyframes scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
Share Improve this question edited Mar 21 at 23:36 Anthony asked Mar 21 at 23:35 AnthonyAnthony 113 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I think this is inherent to your method of doing it, you would rather use requestAnimationFrame() with performance.now() to get a better result !

Here is a small example in plain HTML/CSS with JS

document.addEventListener("DOMContentLoaded", () => {
    const container = document.querySelector('.content');
    /** Duplicating the content for seamless animation */
    const originalChildren = [...container.children];
            originalChildren.forEach(child => {
                const clone = child.cloneNode(true);
                container.appendChild(clone);
            });
            
    let startTime = performance.now();
    let posX = 0;
    const speed = 100; 
    const targetFPS = 120;
    const frameTime = 1000 / targetFPS;
    const resetThreshold = container.offsetWidth / 2;

    function animate(time) {
        let deltaTime = time - startTime;
        if (deltaTime >= frameTime) {
            posX -= speed * deltaTime / 1000;
            if (posX <= -resetThreshold) {
                posX += resetThreshold;
            }
            container.style.transform = `translateX(${posX}px)`;
            startTime = performance.now();
        }
        requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
});
        body {
            margin: 0;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .container {
            position: relative;
            width:500px;
            height: 100px;
            background: lightgray;
            overflow: hidden;
        }
        .content{
         position:absolute;
         left:0;
         top:0;
         display:flex;
         height:100%;
         }
         .logo.red{background:red;}
        .logo {
            height: 80px;
            width: 80px;
            background: blue;
            margin:0 5px;
        }
    <div class="container">
        <div class="content">
          <div class="logo red"></div>
          <div class="logo"></div>
          <div class="logo"></div>
          <div class="logo"></div>
          <div class="logo"></div>
        </div>
    </div>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744329497a4568817.html

相关推荐

  • reactjs - Logo Scroll Carousel Animation Hitching - Stack Overflow

    I am trying to make a logo scroll carousel component that scrolls infinitely. The list of logos is dupl

    7天前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信