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;
Preview:
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