[React + SCSS] 초간단 무한반복 슬라이드 만들기

김방울·2023년 11월 21일
1

React

목록 보기
6/6
post-thumbnail

next 14.0.1 버전을 기준으로 작성되었습니다.

Codepen에서 간단한 원리로 무한반복 슬라이드를 만든 것을 보았는데, 퍼블리싱이나 프론트 작업할때 유용하게 쓸 수 있을 것 같아서 조금 변형해서 사용해봤습니다! 👽

컴포넌트 작성

// infiniteLoop.tsx

import {CSSProperties} from 'react';

const InfiniteLoopSlider : React.FC<InfiniteLoopPropType> = ({children, style, onHoverStop}) => {

  // 슬라이더에 마우스를 올렸을 때 이벤트
  const onMouseOverSlider = (e : React.MouseEvent) => {
    const slider = e.currentTarget;   	
    if (e.target === slider) return; // 슬라이더 자체가 아닌 슬라이더 안의 요소들에 마우스를 올렸을 때 멈추고 싶어 해당 코드를 넣었습니다.   

    if (!(slider instanceof HTMLDivElement)) return;
     slider.style.animationPlayState = 'paused';
  }

  // 마우스가 슬라이더에서 벗어났을 때 이벤트
  const onMouseOutSlider = (e : React.MouseEvent) => {
     const slider = e.currentTarget;

    if (!(slider instanceof HTMLDivElement))  return;
    slider.style.animationPlayState = 'running';
  }


  return (
    <div className='InfiniteLoop__slider' >
      <div 
        className={`InfiniteLoop__inner`} 
        style={style} 
        onMouseOver={onHoverStop ? onMouseOverSlider : undefined} 
        onMouseOut={onHoverStop ? onMouseOutSlider : undefined}
      >
        {children}
        {children}
      </div>
    </div>
  );
};

// TYPE
export interface InfiniteLoopPropType{
  children: React.ReactNode;
  onHoverStop?: boolean;
  style?: CSSProperties; // 기본으로 설정한 스타일 덮어씌우고 싶을 경우
}

export default InfiniteLoopSlider;

CSS 작성

.InfiniteLoop {
// 애니메이션
  @keyframes loop {
    0% {
      transform: translateX(0);
    }
    100% {
      transform: translateX(-50%);
    }
  }
  
  &__slider {
    overflow-x: hidden;
  }
  &__inner {
    display: flex;
    width: fit-content;
    animation: loop;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-duration: 30s;

    & > * {
      flex-shrink: 0;
    }
  }
}

컴포넌트 사용

마우스를 올렸을 때 애니메이션이 멈추는 예시

 		<InfiniteLoopSlider onHoverStop={true}>
            {
              bestItemData.map((el, idx)=> 
                <div className='Main__best-item' key={`title${idx}`}>
                  <div className='Main__best-item-img'>
                    <BlurImage src={el.imgUrl} alt='' fill priority/>
                  </div>
                  <h3 className='Main__best-item-title'>{el.title}</h3>
                  <p className='Main__best-item-desc'>{el.desc}</p>
                </div>
              )
            }
          </InfiniteLoopSlider>

스타일 커스텀 예시


 const partnerCSS : CSSProperties = {
   // 방향을 반대로, 애니메이션 재생 시간을 더 길게 설정
  animationDirection: 'reverse', 
  animationDuration: '55s'
 }
 
 ...(중략)...

 <InfiniteLoopSlider style={partnerCSS}>
              <>
                <div className='Main__partner-item'> </div>
                <div className='Main__partner-item'> </div>
                <div className='Main__partner-item'> </div>
                <div className='Main__partner-item'> </div>
                <div className='Main__partner-item'> </div>
                <div className='Main__partner-item'> </div>
              </>
</InfiniteLoopSlider >

profile
코딩하는 고양이🐱 / UI Developer, Front-end Developer

1개의 댓글

comment-user-thumbnail
2024년 11월 18일

감사합니다!

답글 달기

관련 채용 정보