Skip to content
Merged
Show file tree
Hide file tree
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
69 changes: 58 additions & 11 deletions src/components/Carousel/Carousel.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
import { useState, useEffect } from 'react';
import styles from './Carousel.module.scss';
import RecipientCard from '../RecipientCard/RecipientCard';
import useWindowWidth from '../../hooks/useWindowWidth';

export default function Carousel({ recipients }) {
const [index, setIndex] = useState(0);
const [offsetX, setOffsetX] = useState({}); // μΊλŸ¬μ…€ xμ’Œν‘œ
const [startX, setstartX] = useState(0); // ν„°μΉ˜ 슀크둀 μ‹œμž‘ xμ’Œν‘œ
const [isBouncing, setBouncing] = useState(false); // μΊλŸ¬μ…€ 끝이면 bouncing λͺ¨μ…˜
const isDesktop = useWindowWidth() > 1200;
const [deviceType, setDeviceType] = useState(getDeviceType());
const windowSize = getDeviceType();
const isDesktop = windowSize === 'desktop';
const isMobile = windowSize === 'mobile';

// μΊλŸ¬μ…€ λ²„νŠΌ μž‘λ™κ³Όμ •: button onclick --> settingIndex(), setIndex --> useEffect( setOffsetX(),[index] ): xμ’Œν‘œ μƒνƒœ μ—…λ°μ΄νŠΈ: μΊλŸ¬μ…€ 이동
useEffect(() => {
setOffsetX({
transform: `translateX(-${index * 295}px)`,
});
if (isMobile) {
setOffsetX({
transform: `translateX(-${index * 228}px)`,
});
} else {
setOffsetX({
transform: `translateX(-${index * 295}px)`,
});
}
}, [index]);

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

// ν™”λ©΄ λ¦¬μ‚¬μ΄μ¦ˆ 감지
function getDeviceType() {
const width = window.innerWidth;
if (width < 768) return 'mobile';
if (width <= 1200) return 'bigTablet';
if (width <= 1023) return 'tablet';
return 'desktop';
}

useEffect(() => {
function handleResize() {
const newType = getDeviceType();
const isMobile = deviceType === 'mobile';
const willBeMobile = newType === 'mobile';

// mobile β†’ non-mobile λ˜λŠ” non-mobile β†’ mobile 둜 변경될 λ•Œλ§Œ
const crossedMobileBoundary = isMobile !== willBeMobile;
if (crossedMobileBoundary) {
setIndex(0);
}
if (newType !== deviceType) {
setDeviceType(newType);
}
}

window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, [deviceType]);

// ν„°μΉ˜, 마우슀 λ“œλž˜κ·Έ 감지 --> μΊλŸ¬μ…€ ν•œ μΉΈ 이동
function handleStart(e) {
if (isDesktop) return;
Expand All @@ -45,12 +82,22 @@ export default function Carousel({ recipients }) {
return;
}
} else if (isNext) {
if (index === 5) {
setBouncing(true);
return;
} else if (index < 5) {
settingIndex('next');
return;
if (isMobile) {
if (index === 6) {
setBouncing(true);
return;
} else if (index < 6) {
settingIndex('next');
return;
}
} else {
if (index === 5) {
setBouncing(true);
return;
} else if (index < 5) {
settingIndex('next');
return;
}
}
}
}
Expand Down
13 changes: 0 additions & 13 deletions src/components/Carousel/Carousel.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,6 @@
display: none;
}
}
// νƒœλΈ”λ¦Ώ
@media (max-width: 1023px) {
// .carousel__cardset-wrapper {
// width: 100vw;
// }
// .carousel::before,
// .carousel::after {
// display: none;
// }
// .carousel__direction-button {
// display: none;
// }
}

//λͺ¨λ°”일
@media (max-width: 767px) {
Expand Down
23 changes: 19 additions & 4 deletions src/components/RecipientCard/RecipientCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,27 @@ export default function RecipientCard({ Recipient }) {
} = Recipient;
const navigate = useNavigate();
const [isDragging, setIsDragging] = useState(false);
const [startX, setStartX] = useState(null);

function handleCardClick() {
if (!isDragging) {
navigate(`/post/${id}`);
}
}
function handleStart(e) {
const x = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
setStartX(x);
setIsDragging(false);
}

function handleMove(e) {
if (startX === null) return;
const x = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
const distance = Math.abs(x - startX);
if (distance >= 10) {
setIsDragging(true);
}
}

return (
<div
Expand All @@ -34,10 +49,10 @@ export default function RecipientCard({ Recipient }) {
: {}
}
onClick={handleCardClick}
onMouseDown={() => setIsDragging(false)}
onTouchStart={() => setIsDragging(false)}
onMouseMove={() => setIsDragging(true)}
onTouchMove={() => setIsDragging(true)}
onMouseDown={handleStart}
onTouchStart={handleStart}
onMouseMove={handleMove}
onTouchMove={handleMove}
>
{backgroundColor === 'blue' && <div className={styles.triangle} />}
<h3
Expand Down
14 changes: 0 additions & 14 deletions src/hooks/useWindowWidth.jsx

This file was deleted.