From 5537da9ee664df81cbd1786fdb82f8639972079d Mon Sep 17 00:00:00 2001 From: jhj2713 Date: Tue, 20 Aug 2024 10:48:23 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20transition=20=EB=B2=84=EB=B2=85?= =?UTF-8?q?=EC=9E=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/CasperShowCase/CasperCards.tsx | 4 +- .../TransitionCasperCardItem.tsx | 8 +- .../CasperShowCase/TransitionCasperCards.tsx | 75 +++++++++---------- 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/client/src/features/CasperShowCase/CasperCards.tsx b/client/src/features/CasperShowCase/CasperCards.tsx index a960cc48..1d353d77 100644 --- a/client/src/features/CasperShowCase/CasperCards.tsx +++ b/client/src/features/CasperShowCase/CasperCards.tsx @@ -26,7 +26,7 @@ export function CasperCards({ cardList }: CasperCardsProps) { const totalWidth = (itemWidth + gap) * visibleCardCount; const isEndTopCard = (latestX: number) => { - return latestX <= -totalWidth; + return latestX <= -(CASPER_CARD_SIZE[CASPER_SIZE_OPTION.SM].CARD_WIDTH + gap); }; const isEndBottomCard = (latestX: number) => { return latestX >= 0; @@ -44,7 +44,7 @@ export function CasperCards({ cardList }: CasperCardsProps) { /> void; startAnimation?: () => void; } -export function TransitionCasperCardItem({ +export const TransitionCasperCardItem = memo(function TransitionCasperCardItem({ cardItem, id, stopAnimation, @@ -41,4 +41,4 @@ export function TransitionCasperCardItem({ ); -} +}); diff --git a/client/src/features/CasperShowCase/TransitionCasperCards.tsx b/client/src/features/CasperShowCase/TransitionCasperCards.tsx index 49673914..09dde722 100644 --- a/client/src/features/CasperShowCase/TransitionCasperCards.tsx +++ b/client/src/features/CasperShowCase/TransitionCasperCards.tsx @@ -24,19 +24,19 @@ export function TransitionCasperCards({ isReverseCards = false, }: TransitionCasperCardsProps) { const isAnimated = visibleCardCount <= cardList.length; - const expandedCardList = useMemo(() => [...cardList, ...cardList, ...cardList], [cardList]); const containerRef = useRef(null); const transitionControls = useAnimation(); const [x, setX] = useState(initialX); - const [visibleCardListIdx, setVisibleCardListIdx] = useState(0); + const [visibleCardList, setVisibleCardList] = useState([]); + const [popCardIdx, setPopCardIdx] = useState(cardList.length - 1); const startAnimation = useCallback( (x: number) => { transitionControls.start({ - x: [x, x + diffX * 2], - transition: CARD_TRANSITION(visibleCardCount * 2), + x: [x, x + diffX], + transition: CARD_TRANSITION(visibleCardCount), }); }, [visibleCardCount, transitionControls] @@ -51,41 +51,40 @@ export function TransitionCasperCards({ } }, [transitionControls, containerRef]); - const visibleCardList = useMemo(() => { - const list = expandedCardList.slice( - visibleCardListIdx, - visibleCardListIdx + visibleCardCount * 2 - ); + useEffect(() => { + const currentCardList = cardList.slice(0, visibleCardCount); + const sortedCards = isReverseCards ? currentCardList.reverse() : currentCardList; + setVisibleCardList(sortedCards); + startAnimation(x); + }, []); - if (isAnimated && isReverseCards) { - return list.reverse(); + const updateVisibleCards = (prevCards: CasperCardType[]) => { + const updatedCards = [...prevCards]; + const lastCardIdx = (popCardIdx + 1) % cardList.length; + + if (isReverseCards) { + updatedCards.pop(); + updatedCards.unshift(cardList[lastCardIdx]); + } else { + updatedCards.shift(); + updatedCards.push(cardList[lastCardIdx]); } - return isAnimated ? list : cardList; - }, [ - isReverseCards, - expandedCardList, - cardList, - isAnimated, - visibleCardCount, - visibleCardListIdx, - ]); + setPopCardIdx(lastCardIdx); - useEffect(() => { - startAnimation(x); - }, []); + return updatedCards; + }; const handleUpdateAnimation = (latest: ResolvedValues) => { - if (isEndCard(parseInt(String(latest.x)))) { - let nextIdx = visibleCardListIdx + visibleCardCount; + const currentX = parseInt(String(latest.x), 10); - // 만약 nextIdx가 cardList의 길이를 초과하면 배열의 처음부터 다시 index를 카운트하도록 함 - if (nextIdx >= cardList.length) { - nextIdx = nextIdx % cardList.length; - } + if (isEndCard(currentX)) { + setVisibleCardList((prevCards) => { + const updatedCards = updateVisibleCards(prevCards); + return updatedCards; + }); - setVisibleCardListIdx(nextIdx); - startAnimation(initialX); + startAnimation(isReverseCards ? initialX : initialX); } }; @@ -99,11 +98,11 @@ export function TransitionCasperCards({ style={{ gap: `${gap}px` }} onUpdate={handleUpdateAnimation} > - {visibleCardList.map((card, idx) => ( + {visibleCardList.map((card) => ( startAnimation(x)} /> @@ -111,12 +110,8 @@ export function TransitionCasperCards({ ) : (
    - {visibleCardList.map((card, idx) => ( - + {cardList.map((card) => ( + ))}
)} From 94e43e9d9108e7df638d397c7368908b19afaf0f Mon Sep 17 00:00:00 2001 From: jhj2713 Date: Tue, 20 Aug 2024 11:11:25 +0900 Subject: [PATCH 2/3] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EA=B5=AC=EB=AC=B8=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F?= =?UTF-8?q?=20count=20=EC=88=98=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/features/CasperShowCase/CasperCards.tsx | 4 ++-- client/src/features/CasperShowCase/TransitionCasperCards.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/features/CasperShowCase/CasperCards.tsx b/client/src/features/CasperShowCase/CasperCards.tsx index 1d353d77..3bee17c4 100644 --- a/client/src/features/CasperShowCase/CasperCards.tsx +++ b/client/src/features/CasperShowCase/CasperCards.tsx @@ -39,7 +39,7 @@ export function CasperCards({ cardList }: CasperCardsProps) { initialX={0} gap={gap} diffX={-totalWidth} - visibleCardCount={visibleCardCount} + visibleCardCount={visibleCardCount + 1} isEndCard={isEndTopCard} /> diff --git a/client/src/features/CasperShowCase/TransitionCasperCards.tsx b/client/src/features/CasperShowCase/TransitionCasperCards.tsx index 09dde722..f8a03d9c 100644 --- a/client/src/features/CasperShowCase/TransitionCasperCards.tsx +++ b/client/src/features/CasperShowCase/TransitionCasperCards.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { AnimatePresence, type ResolvedValues, motion, useAnimation } from "framer-motion"; import { CARD_TRANSITION } from "@/constants/CasperShowCase/showCase"; import type { CasperCardType } from "@/types/casper"; From 8e6fb6c282930d8734e70e593419a5b5c127aab8 Mon Sep 17 00:00:00 2001 From: jhj2713 Date: Tue, 20 Aug 2024 11:48:23 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20=EA=B3=B5=ED=86=B5=EB=90=9C=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8=20=EB=B3=80=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/features/CasperShowCase/CasperCards.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/features/CasperShowCase/CasperCards.tsx b/client/src/features/CasperShowCase/CasperCards.tsx index 3bee17c4..95ceec0c 100644 --- a/client/src/features/CasperShowCase/CasperCards.tsx +++ b/client/src/features/CasperShowCase/CasperCards.tsx @@ -24,9 +24,10 @@ export function CasperCards({ cardList }: CasperCardsProps) { const itemWidth = CASPER_CARD_SIZE[CASPER_SIZE_OPTION.SM].CARD_WIDTH; const gap = 40; const totalWidth = (itemWidth + gap) * visibleCardCount; + const paddedCasperWidth = CASPER_CARD_SIZE[CASPER_SIZE_OPTION.SM].CARD_WIDTH + gap; const isEndTopCard = (latestX: number) => { - return latestX <= -(CASPER_CARD_SIZE[CASPER_SIZE_OPTION.SM].CARD_WIDTH + gap); + return latestX <= -paddedCasperWidth; }; const isEndBottomCard = (latestX: number) => { return latestX >= 0; @@ -44,7 +45,7 @@ export function CasperCards({ cardList }: CasperCardsProps) { />