Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 41 additions & 5 deletions src/components/carousel/eventCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,49 @@ function EventCarousel({
const [currList, setCurrList] = useState<(string | StaticImageData)[]>([]); // 화면에 표시될 이미지 리스트 (버퍼 이미지 제외)
const [ButtonActiveIndex, setButtonActiveIndex] = useState(0);
const carouselRef = useRef<HTMLUListElement>(null);
const touchStartRef = useRef<number | null>(null);
const touchEndRef = useRef<number | null>(null);

let noEventImage: StaticImageData | string;

// 버튼 클릭시 보여줄 이미지와 button 상태 변경 함수
const updateIndex = (index: number) => {
// 버튼 클릭시 보여줄 이미지와 button 상태 변경
setCurrIndex(index + 1);
setButtonActiveIndex(index);
};

// 터치 이벤트 함수
const handleTouchStart = (e: React.TouchEvent<HTMLUListElement>) => {
touchStartRef.current = e.touches[0].clientX;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

터치가 시작되면 해당 좌표를 받습니다.

};

const handleTouchMove = (e: React.TouchEvent<HTMLUListElement>) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

터치하고 움직인 거리의 좌표를 받습니다.

touchEndRef.current = e.touches[0].clientX;
};

const handleTouchEnd = () => {
if (touchStartRef.current !== null && touchEndRef.current !== null) {
const diff = touchStartRef.current - touchEndRef.current;
const sensitivity = 50; // 터치 이벤트 감지 감도 (좌우 이동 거리)
if (diff > sensitivity) {
// 오른쪽으로 슬라이드
const newIndex = currIndex === currList.length ? 1 : currIndex + 1;
setCurrIndex(newIndex);
setButtonActiveIndex(newIndex - 1);
} else if (diff < -sensitivity) {
// 왼쪽으로 슬라이드
const newIndex = currIndex === 1 ? currList.length : currIndex - 1;
setCurrIndex(newIndex);
setButtonActiveIndex(newIndex - 1);
}
Comment on lines +48 to +60
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

터치 이벤트 감지 감도를 비교하여, 해당 감도(50)이상 만큼 이동이 있을 경우,
오른쪽인지 왼쪽인지를 감지하여 이전 이미지, 혹은 다음이미지를 보여줍니다.

}
// 터치 이벤트 초기화
touchStartRef.current = null;
touchEndRef.current = null;
};

// 브라우저 사이즈에 따라 pc/mobile용 이미지를 currList에 저장
useEffect(() => {
// 브라우저 사이즈에 따라 pc/mobile용 이미지를 currList에 저장
const updateImageLists = () => {
const width = window.innerWidth;
const isMobile = width < 768;
Expand All @@ -58,8 +91,8 @@ function EventCarousel({
};
}, [eventImages.mobile, eventImages.pc]);

// 이미지 슬라이드 기능
useEffect(() => {
// 이미지 슬라이드 기능
const carousel = carouselRef.current;
if (carousel) {
carousel.style.transition = 'transform 0.5s ease-in-out';
Expand All @@ -85,15 +118,18 @@ function EventCarousel({
<div className="flex-center left-30% absolute bottom-20 z-10 h-20 w-100 gap-10 mobile:bottom-8">
{currList.map((_, idx) => (
<button
className={`h-10 w-10 rounded-full bg-gray-1 hover:bg-primary active:bg-primary ${ButtonActiveIndex === idx ? 'bg-primary' : ''} mobile:h-5 mobile:w-5`}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이놈때문에 버그인줄알고 삽질 너무많이했네요 흑

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

찾아낸 그녀는 정말인지 멋있다 너무....🔥

className={`h-10 w-10 rounded-full bg-gray-1 active:bg-primary ${ButtonActiveIndex === idx ? 'bg-primary' : ''} mobile:h-5 mobile:w-5`}
onClick={() => updateIndex(idx)}
key={idx}
/>
))}
</div>
<ul
className="relative flex h-full w-full scroll-smooth transition-transform"
ref={carouselRef}>
ref={carouselRef}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}>
Comment on lines +130 to +132
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onTouchStart, onTouchMove, onTouchEnd 라는 이벤트가 따로 있더라구요.
터치가 가능한 기기(모바일,테블릿 등)에서만 발생되는 이벤트라고 합니다.
그래서 써봤어용!

  • 사용자가 터치가능한 기기에서만 작동하는 touch Event(모바일, 테블릿 등..)
    • onTouchStart, onTouchMove, onTouchEnd, onTouchCancel
      • [touchstart] 이벤트 - 사용자가 화면에 손가락을 대면 발생.
      • [touchmove] 이벤트 - touchstart 이벤트 후, 손가락을 이동시켰을 때 발생. / 이벤트 핸들러를 등록하여 사용자가 터치 이벤트를 발생시키는 지점을 추적하거나, 드래그 앤 드롭 작업을 구현하는 데 사용됨.
      • [touchend] 이벤트: 사용자가 손가락을 화면에서 떼면 발생. / 이벤트 핸들러를 등록하여 사용자의 터치 이벤트를 감지하고, 해당 이벤트에 대한 처리를 수행하는 데 사용됨.
      • [touchcancel] 이벤트: touchstart 이벤트가 발생한 후, touchmove 이벤트가 발생하지 않고 touchend 이벤트도 발생하지 않는 경우, 이벤트 핸들러를 등록하여 touch 이벤트를 취소하고, 해당 이벤트에 대한 처리를 수행하는 데 사용됨.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 정성스러운 설명 감사해요! 덕분에 저도 onTouchStart, onTouchMove, onTouchEnd 이벤트를 첨 알게 됐네요!!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저두 완전 감동입니다...

{fullImageList.map((image, idx) => (
<li key={idx} className="relative flex w-full flex-shrink-0">
<Image
Expand Down