diff --git a/src/comment/autoScrollCarousel/useAutoCarousel.js b/src/comment/autoScrollCarousel/useAutoCarousel.js index a2949be6..d0136847 100644 --- a/src/comment/autoScrollCarousel/useAutoCarousel.js +++ b/src/comment/autoScrollCarousel/useAutoCarousel.js @@ -3,7 +3,7 @@ import useMountDragEvent from "@/common/useMountDragEvent"; const FRICTION_RATE = 0.1; const MOMENTUM_THRESHOLD = 0.6; -const MOMENTUM_RATE = 0.15; +const MOMENTUM_RATE = 0.3; function useAutoCarousel(speed = 1) { const childRef = useRef(null); @@ -14,15 +14,14 @@ function useAutoCarousel(speed = 1) { const dragging = useRef(false); const prevDragState = useRef({ x: 0, mouseX: 0, prevMouseX: 0 }); const momentum = useRef(speed); + const raf = useRef(null); - useEffect(() => { - if (isControlled) return; - - let progress = true; - timestamp.current = performance.now(); - function animate(time) { + const animate = useCallback( + (time) => { if (childRef.current === null) return; + const width = childRef.current.clientWidth; + // 마우스 뗐을 때 관성 재계산 const baseSpeed = isHovered ? 0 : speed; momentum.current -= (momentum.current - baseSpeed) * FRICTION_RATE; @@ -35,20 +34,26 @@ function useAutoCarousel(speed = 1) { const interval = performance.now() - timestamp.current; setPosition((position) => { const newPos = position + finalSpeed * interval; - return newPos % childRef.current.clientWidth; + return newPos % width; }); // 타임스탬프 저장 timestamp.current = time; - if (progress) requestAnimationFrame(animate); - } - - requestAnimationFrame(animate); + }, + [isHovered, speed], + ); + useEffect(() => { + timestamp.current = performance.now(); + function realAnimate(time) { + animate(time); + raf.current = requestAnimationFrame(realAnimate); + } + raf.current = requestAnimationFrame(realAnimate); return () => { - progress = false; + cancelAnimationFrame(raf.current); }; - }, [isControlled, isHovered, speed]); + }, [isControlled, animate]); // 드래그 도중 함수 const onDrag = useCallback(({ x: mouseX }) => { @@ -83,11 +88,9 @@ function useAutoCarousel(speed = 1) { ref: childRef, eventListener: { onMouseEnter() { - setIsControlled(true); setIsHovered(true); }, onMouseLeave() { - setIsControlled(false); setIsHovered(false); }, onPointerDown(e) { diff --git a/src/comment/commentCarousel/index.jsx b/src/comment/commentCarousel/index.jsx index c73cbc21..f41a5f87 100644 --- a/src/comment/commentCarousel/index.jsx +++ b/src/comment/commentCarousel/index.jsx @@ -1,3 +1,4 @@ +import { useMemo } from "react"; import Suspense from "@/common/Suspense.jsx"; import ErrorBoundary from "@/common/ErrorBoundary.jsx"; import { fetchResource } from "@/common/fetchServer.js"; @@ -6,7 +7,7 @@ import CommentCarouselSkeleton from "./CommentCarouselSkeleton.jsx"; import CommentCarouselError from "./CommentCarouselError.jsx"; function CommentCarouselView() { - const resource = fetchResource("/api/v1/comment"); + const resource = useMemo(() => fetchResource("/api/v1/comment"), []); return ( }> }>