Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- PongWorld
- react native font
- firebase 라이브러리
- 백준
- AWS Access Key
- s3 upload
- 리액트 네이티브 에러
- babel.config.js
- js
- error
- aws bucket 정책
- img upload
- react native 세팅
- 리액트
- GIT
- fire base
- AWS
- 문자열 대소문자
- Access Key 생성
- React
- react native picker
- react native CLI
- 리액트 네이티브
- Project
- 에러
- react native
- react native 개발
- 리엑트 네이티브 아이콘
- Next.js
- 문자열 대소문자 구별
Archives
- Today
- Total
밝을희 클태
[ Next.JS ] 이미지 슬라이더(image-slider) UX 개선 본문


기존에 이미지 슬라이더가 이미지 드래그 도중에 아래 또는 위로 스크롤을 하면 스크롤이 됐다. 그래서 터치 이벤트가 시작될 때 기본 동작을 막아버렸는데 이렇게 되면 문제가 이미지 슬라이더 영역에서는 스크롤이 되지 않아 그 외의 영역을 스크롤해야 했다. 더 좋은 방법이 없을까 고민을 하다가 다른 대기업들의 이미지 슬라이더를 한참을 만져보다가 아이디어가 떠올랐다.
터치 이벤트가 시작이 되고 드래그가 일어날때 y, x의 이동거리를 계산해서 y가 더 크다면 페이지를 스크롤하고, x의 이동거리가 더 크다면 이미지 슬라이더가 드래그되게 하면서 동시에 'touchmove' 이벤트의 기본동작을 막아준다. 정말 별거 아니지만 여기 까지 오는데 시간이 엄청 오래 걸렸다...
touchstart event
const startTouch = useCallback( e => { // 아래의 hook으로 지금 동작이 스크롤중인지 이미지 슬라이더 드래그 중인지 판단 // 처음에는 undefined로 초기화 isScrolling.current = undefined; setIsTransitioning(true); travelRatio.current = 0; // 터치 좌표를 초기화 initDragPos.current = { x: e.touches[0].clientX, y: e.touches[0].clientY }; originOffset.current = offset; // passive 옵션을 false로 지정해줘야 touchmove의 기본 동작을 막을 수 있다. document.addEventListener('touchmove', move, { passive: false }); document.addEventListener('touchend', end); }, [offset, move, end], );
touchmove event
const move = useCallback( e => { const travelX = e.touches[0].clientX - initDragPos.current.x; const travelY = e.touches[0].clientY - initDragPos.current.y; // hook의 값이 undefined 이면 y, x의 이동거리를 계산해서 hook의 값을 변경 // 페이지 스크롤중이라면 'true' 이미지 슬라이더 드래그중이면 'false' if (isScrolling.current === undefined) isScrolling.current = Math.abs(travelY) > Math.abs(travelX); if (isScrolling.current === false) { if ((travelX > 0 && currentImageIndex === 0) || (travelX < 0 && currentImageIndex === images.length - 1)) return; e.preventDefault(); if (Math.abs(travelRatio.current) < 0.8) { travelRatio.current = travelX / clientWidth; if (imageShowRef.current) imageShowRef.current.style.transform = `translateX(${originOffset.current + travelX}px)`; } } }, [clientWidth, currentImageIndex], );