일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 프로그래머스JS
- 자바스크립트
- css기초
- 코딩테스트
- HTML
- 익스프레스
- 백준js
- 백준
- 안드로이드 스튜디오
- 백준알고리즘
- 다이나믹프로그래밍
- 몽고DB
- 백준구현
- 프로그래머스
- HTML5
- 백준골드
- 리액트
- CSS
- dp알고리즘
- 코테
- 포이마웹
- 알고리즘
- js코테
- JS프로그래머스
- 리액트커뮤니티
- 백준구현문제
- JS
- 백준nodejs
- 리액트댓글기능
- 프로그래머스코테
- Today
- Total
개발새발 로그
이미지 슬라이드를 구현하면서 본문
📖들어가며..
이번에는 이미지 슬라이드를 구현해보려고한다.
이미지 슬라이드는 보통 아래와 같은 기능이 존재한다.
- 오른쪽, 왼쪽으로 클릭해서 슬라이드하는 기능
- 페이지네이션
- scroll(모바일 터치시 슬라이드)
위 기능을 하나씩 구현해보려고 한다.
🛠️1. React의 상태로 제어하는 이미지 슬라이드 방식
먼저 기본적으로 React로 이미지 슬라이드를 어떻게 구현하는지 보자
1. 현재 이미지 인덱스를 저장할 상태를 생성한다.
2. 왼쪽 혹은 오른쪽 이동시 currentIndex 값을 변경해줄 함수를 구현한다.
이때 move 함수는 아래와 같은 계산을 한다.
예를 들어 20개의 이미지( 0 ~ 19 )에 19번째에 오고 0번째로 갈 때 19 + 1 + data.length로 40이 되고, 이를 40 % data.length 해서 다시 0번째로 오게합니다.
또 예를 들어 0번에서 왼쪽으로 슬라이드하면 19번으로 가야하므로 0 - 1 + data.length 로 19가 되고, 이를 19 % data.length로 19번째로 오게합니다.
간단하게 말하면 오른쪽으로 이동할 때 (x + 1 + data.length) % data.length 다.
3. 이미지 슬라이드의 left값을 조정한다.
이미지 슬라이드에서 이미지들은 길게 늘어뜨려져있고, 부모 Container에 의해 하나의 이미지만 보이는 상태이다.
그래서 left값을 조정하면 이미지가 슬라이드 되는 것이다.
여기에서 left에 transition을 주면 더 부드럽게 보여줄 수 있다.
4. transitionEnd를 활용해 연속 슬라이드 방지
이미지 슬라이드 기능에서 왼쪽 혹은 오른쪽 버튼을 연속해서 클릭할 때 원하는 결과가 안나올 수 있게된다.
이를 위해 아래와 같이 방지해주는 로직이 필요하다.
그리고 transition이 끝남을 알리는 ontransitionEnd에서 아래와 같이 동작하게 하면 슬라이드 버튼을 연속 클릭해도 하나씩 슬라이드가 가능하게 된다.
그럼 아래와 같이 완성된다.
현재 1번에서 20번으로 갈 때 자연스럽게 왼쪽으로 슬라이드가 되는 것이 아닌 한번에 오른쪽으로 슬라이드를 통해 20번으로 가고 있는데
이는 Carousel을 구현할 때 해결해보려고한다.
Carousel이라는 단어 자체가 컨베이어 벨트라는 것이므로
위에 말한 자연스러운 슬라이딩은 Carousel에 더 적합하다고 생각했다.
🛠️2. CSS의 scroll 기능 활용 방식
첫 번째 방식으로 기능을 만들면 문제가 하나 생긴다.
모바일 환경에서 이미지 슬라이드가 터치로 슬라이드 되지 않는다는 문제다.
모바일 환경에서 터치 슬라이드가 되려면 스크롤이 있어야 한다.
그래서 스크롤 값을 조정해서 슬라이드가 되도록 해보려고 한다.
사실 간단하게 위 코드만 알면 스크롤로 이미지 슬라이드 기능을 구현할 수 있다.
ref를 이용해 이미지 슬라이드하는 요소를 잡고,
해당 값의 현재 scrollLeft를 가져온다음
이미지의 너비 만큼 이동시키면 된다.
원래는 useState를 이용해서도 가능하지만 ref를 사용하면 렌더링을 최소화할 수 있다.
그리고 css속성에서 아래 속성을 사용해줘야한다.
✨scroll-snap-type: x mandatory;
이 속성은 스크롤링 중 요소가 특정 기준(스냅 포인트)에 "착" 붙는 동작을 정의합니다.
- 구성 요소:
- 축(x): 스냅 동작이 가로 방향에 적용됨을 의미합니다. 세로 방향은 y를 사용합니다.
- 유형(mandatory): 스크롤 동작이 강제적으로 스냅 포인트에서 멈추게 합니다.
- mandatory: 사용자가 스크롤할 때 스냅 포인트에서 항상 멈춤.
- proximity: 사용자가 스냅 포인트에 가까운 곳에서 멈추면 스냅 동작 발생.
- 사용 예:
- 여기서 .item은 스냅 포인트가 되는 요소입니다.
- scroll-snap-align 속성을 사용해 각 항목이 어떤 위치에서 스냅할지 지정할 수 있습니다.
.container {
scroll-snap-type: x mandatory;
}
.item {
scroll-snap-align: start;
}
✨overscroll-behavior: contain;
이 속성은 사용자가 스크롤 끝에 도달했을 때의 동작을 정의합니다.
- 작동 방식:
- contain: 스크롤 끝에 도달하더라도 부모나 조상 요소로 스크롤 동작이 전파되지 않습니다.
- 예를 들어, 모바일 브라우저에서 스크롤 끝에 도달할 때 흔히 발생하는 "바운스 효과"를 방지합니다.
- 다른 값:
- auto: 기본 동작으로, 스크롤 이벤트가 부모로 전파될 수 있음.
- none: 스크롤 이벤트가 전파되지 않고, 상위 요소에서도 스크롤이 차단됩니다.
- contain: 스크롤 끝에 도달하더라도 부모나 조상 요소로 스크롤 동작이 전파되지 않습니다.
위 속성들을 통해서 transition 효과가 있는 것처럼 스크롤로도 이미지 슬라이드가 가능해집니다.
예시를 보자
🛠️3. 페이지 네이션 기능 추가
이제 이미지 슬라이드에 페이지 네이션 기능을 추가해보려고한다.
페이지네이션은 자주 쓰이는 기능이므로 컴포넌트화 했다.
먼저 Props로는
totalPages : 전체 페이지 수
currentIndex : 현재 인덱스
visibleCount : 보여줄 페이지 수
handleMove : 페이지 클릭시 이동할 콜백함수
를 받아온다.
이를 통해 아래와 같이 계산할 수 있다.
주석으로 간단하게 설명을 적었다.
요점은 indexes라는 배열을 미리 만들어서 시작점을 찾고, slice로 보여질 page를 계산하는 것이다.
이 부분이 간단해보여서 좋았다.
또 이 코드를 아래와 같이 간단하게 할 수 있다
시작 페이지를 계산하고 이를 바로 배열로 만드는 것이다.
이 방법 또한 간단해보이고, 쉬워보여서 좋았다.
다시 돌아와서 각 페이지 버튼은 아래와 같이 함수가 등록되어있어야 한다.
아래 예시를 보자
📘마치며..
이번에 이미지 슬라이드 기능을 구현하면서
CSS의 scroll-snap-type,
scrollInto와 left를 이용한 방법
페이지네이션 계산방법
모바일 터치를 고려해 추가한 scroll
등을 배울 수 있었다.
이후 Carousel을 만들어보려고하는데 조금 도움이 될 거 같다고 생각된다.
'React' 카테고리의 다른 글
DropDownBox 기능을 구현하면서 (0) | 2025.01.04 |
---|---|
Carousel을 구현하면서 (1) | 2024.12.27 |
팝오버를 구현하면서 (1) | 2024.12.06 |
Modal을 구현하는 방법 - Context API, CreatePortal, Dialog (1) | 2024.11.28 |
SnackBar를 구현하면서...- Context API, CreatePortal (0) | 2024.11.22 |