Skip to content

Commit 5dd4dca

Browse files
authored
Merge pull request codeit-maso#126 from codeit-maso/feature/jeon
🐛 fix: 1. 모바일 진입 또는 벗어나면 캐러셀 위치 리셋. 2. 10미만 드래그는 클릭으로 인식하도록 수정.
2 parents 8515d7d + 336e2bb commit 5dd4dca

File tree

4 files changed

+77
-42
lines changed

4 files changed

+77
-42
lines changed

src/components/Carousel/Carousel.jsx

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,63 @@
11
import { useState, useEffect } from 'react';
22
import styles from './Carousel.module.scss';
33
import RecipientCard from '../RecipientCard/RecipientCard';
4-
import useWindowWidth from '../../hooks/useWindowWidth';
54

65
export default function Carousel({ recipients }) {
76
const [index, setIndex] = useState(0);
87
const [offsetX, setOffsetX] = useState({}); // 캐러셀 x좌표
98
const [startX, setstartX] = useState(0); // 터치 스크롤 시작 x좌표
109
const [isBouncing, setBouncing] = useState(false); // 캐러셀 끝이면 bouncing 모션
11-
const isDesktop = useWindowWidth() > 1200;
10+
const [deviceType, setDeviceType] = useState(getDeviceType());
11+
const windowSize = getDeviceType();
12+
const isDesktop = windowSize === 'desktop';
13+
const isMobile = windowSize === 'mobile';
1214

1315
// 캐러셀 버튼 작동과정: button onclick --> settingIndex(), setIndex --> useEffect( setOffsetX(),[index] ): x좌표 상태 업데이트: 캐러셀 이동
1416
useEffect(() => {
15-
setOffsetX({
16-
transform: `translateX(-${index * 295}px)`,
17-
});
17+
if (isMobile) {
18+
setOffsetX({
19+
transform: `translateX(-${index * 228}px)`,
20+
});
21+
} else {
22+
setOffsetX({
23+
transform: `translateX(-${index * 295}px)`,
24+
});
25+
}
1826
}, [index]);
1927

2028
function settingIndex(direction) {
2129
setIndex((prev) => (direction === 'next' ? prev + 1 : prev - 1)); // next? next index : back index
2230
}
2331

32+
// 화면 리사이즈 감지
33+
function getDeviceType() {
34+
const width = window.innerWidth;
35+
if (width < 768) return 'mobile';
36+
if (width <= 1200) return 'bigTablet';
37+
if (width <= 1023) return 'tablet';
38+
return 'desktop';
39+
}
40+
41+
useEffect(() => {
42+
function handleResize() {
43+
const newType = getDeviceType();
44+
const isMobile = deviceType === 'mobile';
45+
const willBeMobile = newType === 'mobile';
46+
47+
// mobile → non-mobile 또는 non-mobile → mobile 로 변경될 때만
48+
const crossedMobileBoundary = isMobile !== willBeMobile;
49+
if (crossedMobileBoundary) {
50+
setIndex(0);
51+
}
52+
if (newType !== deviceType) {
53+
setDeviceType(newType);
54+
}
55+
}
56+
57+
window.addEventListener('resize', handleResize);
58+
return () => window.removeEventListener('resize', handleResize);
59+
}, [deviceType]);
60+
2461
// 터치, 마우스 드래그 감지 --> 캐러셀 한 칸 이동
2562
function handleStart(e) {
2663
if (isDesktop) return;
@@ -45,12 +82,22 @@ export default function Carousel({ recipients }) {
4582
return;
4683
}
4784
} else if (isNext) {
48-
if (index === 5) {
49-
setBouncing(true);
50-
return;
51-
} else if (index < 5) {
52-
settingIndex('next');
53-
return;
85+
if (isMobile) {
86+
if (index === 6) {
87+
setBouncing(true);
88+
return;
89+
} else if (index < 6) {
90+
settingIndex('next');
91+
return;
92+
}
93+
} else {
94+
if (index === 5) {
95+
setBouncing(true);
96+
return;
97+
} else if (index < 5) {
98+
settingIndex('next');
99+
return;
100+
}
54101
}
55102
}
56103
}

src/components/Carousel/Carousel.module.scss

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,6 @@
9494
display: none;
9595
}
9696
}
97-
// 태블릿
98-
@media (max-width: 1023px) {
99-
// .carousel__cardset-wrapper {
100-
// width: 100vw;
101-
// }
102-
// .carousel::before,
103-
// .carousel::after {
104-
// display: none;
105-
// }
106-
// .carousel__direction-button {
107-
// display: none;
108-
// }
109-
}
11097

11198
//모바일
11299
@media (max-width: 767px) {

src/components/RecipientCard/RecipientCard.jsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,27 @@ export default function RecipientCard({ Recipient }) {
1616
} = Recipient;
1717
const navigate = useNavigate();
1818
const [isDragging, setIsDragging] = useState(false);
19+
const [startX, setStartX] = useState(null);
1920

2021
function handleCardClick() {
2122
if (!isDragging) {
2223
navigate(`/post/${id}`);
2324
}
2425
}
26+
function handleStart(e) {
27+
const x = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
28+
setStartX(x);
29+
setIsDragging(false);
30+
}
31+
32+
function handleMove(e) {
33+
if (startX === null) return;
34+
const x = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
35+
const distance = Math.abs(x - startX);
36+
if (distance >= 10) {
37+
setIsDragging(true);
38+
}
39+
}
2540

2641
return (
2742
<div
@@ -34,10 +49,10 @@ export default function RecipientCard({ Recipient }) {
3449
: {}
3550
}
3651
onClick={handleCardClick}
37-
onMouseDown={() => setIsDragging(false)}
38-
onTouchStart={() => setIsDragging(false)}
39-
onMouseMove={() => setIsDragging(true)}
40-
onTouchMove={() => setIsDragging(true)}
52+
onMouseDown={handleStart}
53+
onTouchStart={handleStart}
54+
onMouseMove={handleMove}
55+
onTouchMove={handleMove}
4156
>
4257
{backgroundColor === 'blue' && <div className={styles.triangle} />}
4358
<h3

src/hooks/useWindowWidth.jsx

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)