i-hate-scales(2)-슬라이더
2023-05-18
기타의 스케일들을 보기 쉽게 슬라이더로 넘기면서 볼 수 있도록
슬라이더 라이브러리를 만들고 이를 NPM 으로 배포할 생각이다
이 포스팅은 styled-component 로 만들어져
styled-component를 모르면 이해가 어려울 수 있습니다
방법
방법 자체는 간단하다
사진들을 display:flex로 가로로 길게 늘어트리고
overflow : hidden 으로 넘친 부분을 숨긴 후
사용자 액션(버튼, 드래그)가 감지 되면 그에 맞게 translateX 를 조정해주면 된다
translateX 외에 다른 방법도 있지만 translateX가 HTML 랜더링 최종 단계인
composite 단계에서 계산되기에 버벅거리는 애니메이션 없이 부드럽게
적용된다
구현
가장 간단한 방법은 슬라이드 하나의 크기를 구한 후
다음 슬라이드로 이동 될때 슬라이드 하나의 크기 만큼 translateX를 마이너스 해주면
슬라이드가 구현된다
핵심 코드만 몇가지 설명하겠다
Slides 컴포넌트는 slideSize, slideIndex dragPos 값을 사용하는데
slideSize는 말 그대로 슬라이드 하나의 사이즈이고
slideIndex는 말 그대로 slide의 index이다
dragPos는 버튼이아닌 드래그로 했을때를 위한 값이며 아래에 더 자세하게 설명하겠다
slideIndex가 업데이트 즉 사용자가 슬라이드를 왼쪽 혹은 오른쪽으로 이동시키도록 이벤트를
발생 시켰을때
slideIndex 를 업데이트 시켜 translateX위치를 옮겨 다음 혹은 이전 슬라이드가 나오도록 한다
기다란 flex box를 translateX로 왼쪽으로 옮기는 방식을 사용하기에 다음 슬라이드로 이동하면
translateX를 마이너스로 해야하고 이전 슬라이드로 이동하면 플러스 해야한다
move 함수를 통해 type 이 next면 현재 슬라이드 인덱스에서 +1 해주고
prev 면 -1을 해준다
여기서 주의해야 할점은 애니메이션인데 부드러운 이동효과를 주고 싶으면 슬라이드에
위 옵션을 주면 애니메이션을 줄 수 있는데
만약 애니메이션 도중 사용자가 다시 이동 이벤트를 주게 되면 애니메이션 도중에
슬라이드가 휙휙 바뀌는 보기 싫은 애니메이션이 되버리는데 이를 방지 할 방법이 있다
다음 코드를 보자
relocation 함수는 아래에서 자세히 설명하겠다
move 함수가 실행 되었을때 animation 상태값을 true로 해주고
0.3초 만큼의 setTimeout을 준다(애니메이션이 0.3이기 때문에)
setTimeout이 실행되면 animation을 다시 false로 해 move 함수가 다시 작동될 수 있도록 해주면
애니메이션이 실행되는 동안은 사용자가 다음 슬라이드로 옮길 수 없게 되어 좀더
부드러운 슬라이드 애니메이션의 구현이 가능하게 된다
무한 슬라이드
무한 슬라이드는 약간의 눈속임을 필요로 한는데
방식은 이렇다
기존 슬라이드에 맨앞에 마지막 슬라이드를 맨뒤에 처음 슬라이드를
하나씩 더 넣어준 후 slideIndex의 기본값을 0이 아닌 1로 넣어주면 된다
다음 코드를 보자
slide를 요소들을 가공해주는 함수로
슬라이드 맨앞, 맨뒤에 하나씩 슬라이드를 더 넣어 준다
RenderSlides 는 꼭 useMemo를 통해 memoization을 해주는게 좋다 이 과정을 수행 해주지 않으면 컴포넌트가 업데이트(슬라이드 이동) 할때 마다 Slide를 재랜더링 하게 되는데 슬라이드 하나 하나가 단순하다면 상관 없지만 여러 요소를 포함 하고 있을 경우 많은 성능 저하가 보이게 되니 꼭 memoization을 하자
그 후 사용자가 처음 슬라이드에서 뒤로 이동하게 되면
위 함수를 통해 삽입한 슬라이드를 보여준 후 애니메이션이 끝난 후
slideIndex를 실제 마지막 슬라이드로 옮겨주면 된다
이 과정을 수행 해주는 함수가 relocation 함수이다
이 함수를 통해 index가 0이거나 마지막 인덱스로 이동하게 된다면
slideIndex를 실제 마지막, 처음 슬라이드로 이동 시켜 준다
다만 relocation과 같은 함수가 실행 될때에는 꼭 애니메이션을 비활성화 해주자
만약 애니메이션이 그대로 활성화 되어있다면 갑자기 슬라이드가
끝에서 끝으로 이동하는 모습이 애니메이션에서 그대로 보이기에
애니메이션이 비활성화 되어야 사용자가 눈속임을 알아차리기 못하고
자연스러운 전환이 가능해진다
마치며
슬라이더는 생각보다 간단하게 만들 수 있는 기능이어서 이런 저런 기능을 추가하는게
재미있었던 프로젝트였다
풀코드는 다음 깃허브 링크에서 볼 수 있다
또한 npm 라이브러리로 설치해 볼수도 있다
스케일을 사용해 직접 만든 사이트