어제 무한 carousel을 구현하기 위해 많은 시간을 보냈다. 1번에서 2번으로 넘어갈 때 끊겨서 나오는 문제가 있었다.
당시에는 새벽이라 머리가 멈춰있었던 것 같다.
일단 구현한 원리를 잘 생각해보았다. 기존의 데이터 처음이나 마지막 인덱스에 접근했을 때 미리 설정했던 임의 인덱스로 보내야 했다.
일단 이것 부터 확인을 했다.
curIndex
를 확인하면서 슬라이드를 했을 때 올바르게 인덱스가 찍히는지 확인했다.
테스트를 진행해보니 가장 처음 렌더링이 되었을 때는 1번에서 2번으로 부드럽게 넘어갔다. 그리고 한 바퀴를 돌고 다시 1번에서 2번이 될 때, 2번이 끊겨서 보였다.
확인을 해보니 마지막 아이템으로 넘어갔을 때 1번으로 인덱싱의 되어야 되는데, 마지막 + 1로 인덱싱이 되고, 2번으로 바뀌는 것 때문에 끊겨서 보이는 것이다.
해결 방법은 아주 간단했다. 마지막 요소에 접근했을 때 처리하는 부분의 범위가 +1이었기 때문에 -1로 해결 했다.
if (index - 2 < 0) {
index += ORIGINSIZE;
replaceSlide(index);
} else if (index - 2 >= ORIGINSIZE - 1) {
index -= ORIGINSIZE;
replaceSlide(index);
}
ORIGINSIZE - 1
로 설정을 하니 문제 없이 작동했다.
스와이핑을 하려면 뭘 해야할까 고민했다.
const getClientX = (event) => {
return event._reactName === "onTouchStart"
? event.touches[0].clientX
: event._reactName === "onTouchMove" || event._reactName === "onTouchEnd"
? event.changedTouches[0].clientX
: event.clientX;
};
const handleTouchStart = (e) => {
setPrevSlideX((prevSlideX) => getClientX(e));
};
const handleTouchMove = (e) => {
if (prevSlideX) {
setSlideX((slideX) => getClientX(e) - prevSlideX);
}
};
const handleMouseSwipe = (e) => {
if (slideX) {
const currentTouchX = getClientX(e);
if (prevSlideX > currentTouchX + 100) {
handleSlide(curIndex + 1);
} else if (prevSlideX < currentTouchX - 100) {
handleSlide(curIndex - 1);
}
setSlideX((slideX) => null);
}
setPrevSlideX((prevSlideX) => null);
};
코드로 구현 하면 이런 로직을 가지게 된다. 로직이 복잡한 것이 아니라 터치에 대한 개념만 있다면 조금 쉽게 구현이 가능하다.
그래서 라이브러리 없이 스와이프가 가능한 무한 캐러셀을 만들었다!