좌우로 반복되는 롤링배너

UI

  • slide
  • banner

2023-04-22 21:56

✍🏻 Table Of Contents

사용한 패키지

npm install @emotion/styled
bash

설치

npm install @emotion/react @emotion/styled
bash

코드

import styled from "@emotion/styled";
import React, { useEffect, useState } from "react";

const RollingBanner = ({ speed, children }) => {
  const [moveX, setMoveX] = useState(0);
  const [direction, setDirection] = useState(1);

  useEffect(() => {
    if (typeof window !== "object") return;

    if (children.length > 3) {
      const scroll = document.querySelector("#slide-wrapper").scrollWidth;
      const offset = document.querySelector("#slide-wrapper").offsetWidth;

      const check = Math.floor(scroll / offset);

      const move = setInterval(() => {
        setMoveX((prev) => prev + speed * direction);
        document.querySelector("#slide-wrapper").style.transform = `translateX(-${moveX}px)`;
      }, 100);

      if (moveX >= offset * (check - 1) + scroll - offset * check) {
        setDirection(-1);
      } else if (moveX <= 0) {
        setDirection(1);
      }

      return () => {
        clearInterval(move);
      };
    }
  }, [moveX, direction]);

  return (
    <Container id="container">
      <SlideWrapper id="slide-wrapper">
        {children.length > 1 ? (
          children.map((v, i) => {
            return <SlideItem key={i}>{v}</SlideItem>;
          })
        ) : (
          <SlideItem>{children}</SlideItem>
        )}
      </SlideWrapper>
    </Container>
  );
};

export default RollingBanner;

const Container = styled.div`
  overflow: hidden;
`;

const SlideWrapper = styled.ul`
  display: flex;
  gap: 1rem;
  padding: 2rem;
  @media (max-width: 768px) {
    padding: 1rem;
  }
  transition: all 0.3s;
`;

const SlideItem = styled.li`
  padding: 1rem;
  display: flex;
  justify-content: center;
  align-items: center;

  > img {
    width: 50px;
    height: auto;
  }
`;
javascript

사용

<RollingBanner speed={5}>
	<슬라이드 아이템1/>
	<슬라이드 아이템2/>
	<슬라이드 아이템3/>
	<슬라이드 아이템4/>
	<슬라이드 아이템5/>
</RollingBanner>

javascript