"use client"; import Image from "next/image"; import { useEffect, useMemo, useRef, useState } from "react"; type Slide = { src: string; alt?: string }; type Props = { slides: Slide[]; className?: string; maxWidthClassName?: string; autoPlayMs?: number; imageHeightClassName?: string; }; const PER_VIEW = 2; export default function CaseImageSlider({ slides, className = "", maxWidthClassName = "max-w-[700px]", autoPlayMs = 4500, imageHeightClassName = "h-[340px]", }: Props) { const safeSlides = useMemo(() => slides.filter(Boolean), [slides]); const [page, setPage] = useState(0); const [dragging, setDragging] = useState(false); const [isHover, setIsHover] = useState(false); const startX = useRef(0); const deltaX = useRef(0); const pageCount = Math.ceil(safeSlides.length / PER_VIEW); const canSlide = pageCount > 1; const goTo = (nextPage: number) => { if (!canSlide) return; if (nextPage < 0) setPage(pageCount - 1); else if (nextPage >= pageCount) setPage(0); else setPage(nextPage); }; const goNext = () => goTo(page + 1); const goPrev = () => goTo(page - 1); // ✅ 자동롤링 (hover 시 정지 포함) useEffect(() => { if (!canSlide || dragging || isHover) return; const timer = window.setInterval(() => { setPage((prev) => (prev + 1 >= pageCount ? 0 : prev + 1)); }, autoPlayMs); return () => window.clearInterval(timer); }, [canSlide, dragging, isHover, pageCount, autoPlayMs]); // ✅ swipe const onPointerDown = (e: React.PointerEvent) => { if (!canSlide) return; setDragging(true); startX.current = e.clientX; deltaX.current = 0; e.currentTarget.setPointerCapture(e.pointerId); }; const onPointerMove = (e: React.PointerEvent) => { if (!dragging) return; deltaX.current = e.clientX - startX.current; }; const onPointerUp = () => { if (!dragging) return; setDragging(false); const threshold = 50; if (deltaX.current > threshold) goPrev(); if (deltaX.current < -threshold) goNext(); deltaX.current = 0; }; if (!safeSlides.length) return null; return (
setIsHover(true)} // ✅ hover 시작 → 정지 onMouseLeave={() => setIsHover(false)} // ✅ hover 끝 → 재시작 onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={onPointerUp} onPointerCancel={onPointerUp} >
{Array.from({ length: pageCount }).map((_, pageIndex) => { const pageSlides = safeSlides.slice( pageIndex * PER_VIEW, pageIndex * PER_VIEW + PER_VIEW ); return (
{pageSlides.map((slide, i) => (
{slide.alt
))}
); })}
{/* 도트 */} {canSlide && (
{Array.from({ length: pageCount }).map((_, i) => (
)}
); }