캐로셀 구조


많은 웹사이트에서 여러 이미지를 슬라이드 형식으로 보여주기 위해 사용하는 캐로셀 뷰어는 생각보다 간단하게 구현할 수 있다. 캐로셀 뷰어의 DOM 구조는 대략 아래와 같다.

<div> <!-- 캐로셀 아이템 Wrapper -->
	<div> <!-- 캐로셀 아이템 Parent -->
		<div /> <!-- 캐로셀 아이템 A -->
		<div /> <!-- 캐로셀 아이템 B -->
		<div /> <!-- 캐로셀 아이템 C -->
	</div>
</div>
  1. 캐로셀 아이템 Wrapper : 넘침 영역 숨김 처리 *overflow: hidden; width: 100%; height: 100%;*
  2. 캐로셀 아이템 Parent : 여러개의 캐로셀 아이템을 감싸는 부모 ⚡️
  3. 캐로셀 아이템 : 1개 아이템만 보이도록 처리 *width: 100%; flex-grow: 1; flex-shrink: 0;*

그림으로 표현하면 아래 같은 구조가 된다. 각 캐로셀 아이템의 폭이 100%(Parent 요소 너비)이므로 화면엔 1개 아이템만 보인다(Item A). Parent 요소의 translateX 값을 -100% 로 설정하면 자신 너비 만큼 좌측으로 이동해서 두번째 아이템(Item B)이 화면에 보인다. 여기에 transition: transform 250ms linear; 같은 속성을 주면 캐로셀 아이템이 움직이는 듯한 효과를 줄 수 있다.

carousel.png

React에서 구현


React에선 현재 아이템에 대한 Index를 상태로 두고(currentIndex) 100을 곱하는 방식으로 구현할 수 있다. Index 상태는 Next 버튼을 누르면 1씩 늘어나고, Prev 버튼을 누르면 1씩 감소한다.

const [currentIndex, setCurrentIndex] = useState(0);
  // Item A : Index 0 -> translateX(-0%);
  // Item B : Index 1 -> translateX(-100%);
  // Item C : Index 2 -> translateX(-200%);
  // ...

return (
  <div // 캐로셀 아이템 Parent
    className='flex no-scrollbar transition-all ease-linear'
    style={{
      transform: `translateX(-${currentIndex * 100}%)`,
      transitionDuration: `${speed}ms`,
    }}
  >
    {children} {/* 캐로셀 아이템 */}
  </div>
);

아이템 width와 translateX 관계 ⚡️


화면에 표시되는 아이템 개수를 변경하고 싶으면 아이템의 폭을 수정한다. 슬라이드 할 때의 아이템 개수를 변경하고 싶으면 translateX 부분에서 현재 인덱스 뒤에 곱하는 숫자를 수정하면 된다.