Preview:
import React, { useRef, useEffect } from 'react';
import styled, { keyframes } from 'styled-components';
import PropTypes from 'prop-types';
import digitalMarketing from "../assets/digitalMarketing.png"

const WrapperContainer = styled.div`
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background-color: #ccc;
`;

const Wrapper = ({ children }) => {
  return <WrapperContainer>{children}</WrapperContainer>;
};

const moveLeft = keyframes`
  from {
    transform: translateX(0);
  }
`;

const MarqueeContainer = styled.div`
  position: relative;
  width: 400px;
  margin-top: 20px;
  padding: 10px 0;
  background-color: white;
  overflow: hidden;
  &:hover {
    animation-play-state: paused;
  }
  &::after {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    pointer-events: none;
    background-image: linear-gradient(
      to right,
      #ccc,
      transparent 20%,
      transparent 80%,
      #ccc
    );
  }
`;

const MarqueeArea = styled.div`
  display: inline-block;
  white-space: nowrap;
  transform: translateX(-${(props) => props.move}px);
  animation: ${moveLeft} ${(props) => props.time}s linear infinite
    ${(props) => (props.toRight ? " reverse" : "")};
  animation-play-state: inherit;
`;

const MarqueeItem = styled.div`
  position: relative;
  display: inline-block;
  margin-right: 2em;
`;

const getFillList = (list, copyTimes = 1) => {
  let newlist = [];
  for (let i = 0; i < copyTimes; i++) {
    newlist.push(...list);
  }
  return newlist;
};

const Marquee = ({ images, time, toRight, ...props }) => {
  const marqueeContainer = useRef(null);
  const marqueeArea = useRef(null);
  const [moveLeft, setMoveLeft] = React.useState(0);
  const [showImages, setShowImages] = React.useState(images);
  const [realTime, setRealTime] = React.useState(time);

  useEffect(() => {
    const containerWidth = Math.floor(marqueeContainer.current.offsetWidth);
    const areaWidth = Math.floor(marqueeArea.current.scrollWidth);
    const copyTimes = Math.max(2, Math.ceil((containerWidth * 2) / areaWidth));
    const newMoveLeft = areaWidth * Math.floor(copyTimes / 2);
    const newRealTime = time * parseFloat((newMoveLeft / containerWidth).toFixed(2));
    setShowImages(getFillList(images, copyTimes));
    setMoveLeft(newMoveLeft);
    setRealTime(newRealTime);
  }, [images]);

  return (
    <MarqueeContainer ref={marqueeContainer} {...props}>
      <MarqueeArea ref={marqueeArea} move={moveLeft} time={realTime} toRight={toRight}>
        {showImages.map((image, index) => {
          return (
            <MarqueeItem key={index}>
              <img
                src={image}
                alt={`Image ${index + 1}`}
                width="100"
                height="100"
              />
            </MarqueeItem>
          );
        })}
      </MarqueeArea>
    </MarqueeContainer>
  );
};

Marquee.propTypes = {
  images: PropTypes.array,
  time: PropTypes.number,
  toRight: PropTypes.bool,
};

Marquee.defaultProps = {
  images: [],
  time: 10,
};

function Awards() {
  // Example image URLs
  const IMAGE_LIST = [digitalMarketing, digitalMarketing, digitalMarketing,digitalMarketing];

  return (
    <Wrapper>
      <Marquee images={IMAGE_LIST} time={5} />
    </Wrapper>
  );
}

export default Awards;
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter