캐러쉘의 어원은 회전목마...라고 동기분이 말해줬다.
빙빙 돌아가는 회전목마처럼... 부드럽게 넘어가는 슬라이드를 제작해보자!
외부라이브러리를 쓰면 쉽게 만들 수 있지만, 이번 1차 프로젝트에서는 외부라이브러리 사용 없이 구현해보라고 하셔서 쌩으로 제작해보았다..^^
<div className="carouselWrapper">
<div
className="carousel"
style={{ transform: `translateX(${move}px)` }}
>
<div className="recommendTitleBox">
<p>함께 사용하기 좋은 제품</p>
</div>
{ITEM_CARD_DATA.map(el => {
return (
<ItemCard
key={el.id}
name={el.name}
img={el.img}
description={el.description}
/>
);
})}
</div>
</div>
우선 전체를 감싸는 div박스를 만들고 carouselWrapper라고 클래스명을 붙여주었다. 그 아래 carousel div를 만들고 그 안에서 컴포넌트로 만든 이미지카드를 map()함수를 이용해 반복해주었다.
.carouselWrapper {
position: relative;
width: 1200px;
height: 550px;
margin: 0 auto;
overflow-x: hidden;
.carousel {
display: flex;
position: absolute;
transition: 0.5s;
.imgBox {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
.image {
width: 389px;
height: 400px;
margin-top: 50px;
}
.image:hover ~ .text .recommendedItemName {
text-decoration: underline;
text-decoration-thickness: 1px;
cursor: pointer;
}
}
}
}
부모태그인 carouselWrapper에 position: relative
를 주고 자식요소인 carousel에는 position: absolute
를 주었다. 그리고 wrapper에 overflow-x: hidden
을 주어 옆으로 빠져나온 이미지카드들이 박스 안에서만 보일 수 있게 만들었다.
const IMG_WIDTH = 389;
const [move, setMove] = useState(0);
const moveRight = () => {
if (move >= -(ITEM_CARD_DATA.length * IMG_WIDTH) + IMG_WIDTH * 3) {
setMove(move - IMG_WIDTH);
}
};
const moveLeft = () => {
if (move <= -IMG_WIDTH) {
setMove(move + IMG_WIDTH);
}
};
우선 이미지카드의 가로길이값을 구한 후 IMG_WIDTH라는 변수에 저장해주었다.
오른쪽으로 움질일 때와 왼쪽으로 움직일 때의 함수를 각각 만들어 이미지카드의 길이를 저장해둔 변수와 배열의 길이를 활용하여 캐러쉘이 이동할 수 있는 범위를 지정해주었다. 그리고 함수를 실행할 때 IMG_WIDTH의 값만큼 움직이게 해주었다.
이제 버튼을 누르면 이미지 한개만큼 슬라이드가 이동하고, 양 끝으로 가면 더이상 이동하지 않는다.
<img
src="/images/leftArrow.png"
className="leftArrow"
onClick={moveLeft}
alt="화살표 아이콘"
/>
<img
src="/images/rightArrow.png"
className="rightArrow"
onClick={moveRight}
alt="화살표 아이콘"
/>
위에서 만든 moveLeft와 moveRight 함수를 각 버튼의 onClick 안에서 실행시켜주었다.