웹사이트에서 흔히 볼 수 있는, 왼쪽과 오른쪽에 화살표가 있고 클릭을 할 때마다 옆의 이미지로 넘어가는 흔히들 이미지 슬라이드라고 하는 기능의 정식명칭은 Carousel이라고 한다.
react에서 이런 캐러샐 기능을 구현하는 방법을 찾아봤을 때 가장 많이 나오는건 바로 라이브러리였다.
라이브러리를 설치하면 간단하게 구현할 수 있지만 이번 1차 프로젝트에서는 라이브러리 사용이 제한되어있기 때문에.. 다시 구글링!
여러가지 방법을 검색해 본 결과 나에게 맞는 방법은 translate를 이용해 클릭할 때마다 위치를 옮겨주는 것!
이미지들이 옆으로 차곡차곡 쌓여있는 컨테이너를 만들고 그 컨테이너를 화면크기만큼만 보여준다!(overflow: hidden으로 화면 크기를 벗어난 부분은 안보이도록 하기!)
그 뒤 그림의 크기만큼 translate를 이용해 옮겨주면 기능 구현 완료!
실행 화면!
전체 코드!
설명과 함께 코드를 뜯어보면 이렇다.this.state = { bannerImg: [], pageNum: 1, };
배너에 들어갈 사진들을 mock data로 모아 map함수를 이용해 저 bannerImg라는 빈 배열에 담아주었다.
그리고 배너 하나마다 해당하는 번호를 주기 위해 pageNum 이라는 스테이트를 생성했다.
nextBtn = () => { const { pageNum, bannerImg } = this.state; let index = pageNum; if (index === bannerImg.length) { index = 0; } index = index + 1; this.setState({ pageNum: index, }); }; prvBtn = () => { const { pageNum, bannerImg } = this.state; let index = pageNum; if (index === 1) { index = bannerImg.length + 1; } index = index - 1; this.setState({ pageNum: index, }); };
nextBtn은 누를 때마다 pageNum 이 1씩 커진다. 다만 마지막 페이지(배너의 개수와 같다)까지 갔다면 다시 처음으로 돌아오도록 (버튼을 누르면 1씩 커지기 때문에 0으로 값을 설정해야 클릭 했을 때 처음 PageNum인 1로 올 수 있다)한다.
PrevBtn도 같은 원리로 작성해준다.
render() { const { bannerImg, pageNum } = this.state; const { prvBtn, nextBtn } = this; let transNum = 1920 * ((bannerImg.length - 1) / 2); if (pageNum > 1) { transNum = 1920 * ((bannerImg.length - 1) / 2) - 1920 * (pageNum - 1); } return ( <> <div className="mainBanner"> <ul className="bannerBox" style={{ transform: `translate(${transNum}px)` }}
내가 선택한 배너의 길이는 1920px이기 때문에 1920px이 기준이 된다.
그리고 난 페이지 전체를 가운데 정렬을 맞춰놨기 때문에 transNum이 0이라면 컨테이너가 가운데 이미지를 내보내고 있게 된다. 그러므로 배너의 개수에 맞춰 제일 첫번째 배너를 보여줄 수 있게끔 초기 transNum을 설정해 위치를 조정해주었다.이제 클릭할 때마다 움직이는 값을 설정을 해주었는데 저 공식은 배너의 수가 홀수 일 때 클릭 한 번 할 때마다 1920px씩 움직이도록 설정해놓았다.
추가로 수정하고 싶은 사항들!
시간이 된다면 아직 더 해결하고 싶은 문제가 많은 코드지만 이렇게 정리를 하며 다시 한 번 내 것으로 만든다는데 의미가 있는 것 같다.