1- import { motion } from "motion/react" ;
1+ import { AnimatePresence , motion } from "motion/react" ;
22import { Dialog } from "radix-ui" ;
33import { useEffect } from "react" ;
4- import assetHighlight from "@/assets/images/ic_highlight.png" ;
5- import assetBadge from "@/assets/images/ic_levelup_badge.png" ;
6- import assetGradient from "@/assets/images/ic_levelup_gr.png" ;
4+ import assetLevelup from "@/assets/images/levelup.png" ;
75import assetTextLevelup from "@/assets/images/text_levelup.png" ;
86
97interface LevelUpPopupProps {
@@ -19,73 +17,46 @@ export const LevelUpPopup = ({ isOpen, onClose }: LevelUpPopupProps) => {
1917 const timer = setTimeout ( ( ) => {
2018 onClose ( ) ;
2119 } , 3000 ) ;
22-
2320 return ( ) => clearTimeout ( timer ) ;
2421 }
2522 } , [ isOpen , onClose ] ) ;
2623
2724 return (
2825 < Dialog . Root open = { isOpen } onOpenChange = { onClose } >
29- < Dialog . Portal >
30- < Dialog . Content className = "fixed inset-0 z-50 bg-neutral-800" >
31- { /* 레벨업 텍스트와 뱃지 */ }
32- { /* 배경 그라데이션 */ }
33- < div className = "absolute inset-0 flex flex-center" >
34- < motion . img
35- className = "absolute object-cover w-full h-full top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
36- src = { assetGradient }
37- alt = "백그라운드 그라데이션"
38- />
39- { /* 하이라이트 - 360도 회전 */ }
40- < div className = "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[500px] h-[500px]" >
26+ < AnimatePresence >
27+ < Dialog . Portal >
28+ < Dialog . Content className = "fixed inset-0 z-50 bg-neutral-800 max-w-[600px] mx-auto" >
29+ { /* 레벨업 텍스트와 뱃지 */ }
30+ { /* 배경 그라데이션 */ }
31+ < div className = "absolute inset-0 flex flex-center" >
4132 < motion . img
42- className = "absolute object-cover will-change-transform w-full h-full"
43- src = { assetHighlight }
44- alt = "하이라이트"
45- animate = { {
46- rotate : 360 ,
33+ className = "z-20 max-w-[240px] w-full object-cover absolute top-[20%]"
34+ src = { assetTextLevelup }
35+ alt = "레벨업"
36+ initial = { { y : 50 , opacity : 0 } }
37+ animate = { { y : 0 , opacity : 1 } }
38+ transition = { {
39+ duration : 0.6 ,
40+ type : "spring" ,
41+ bounce : 0.6 ,
42+ delay : 0.3 ,
4743 } }
44+ />
45+ < motion . img
46+ className = "absolute object-cover w-full h-full top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
47+ src = { assetLevelup }
48+ alt = "백그라운드 그라데이션"
49+ initial = { { opacity : 0 } }
50+ animate = { { opacity : 1 } }
4851 transition = { {
49- duration : 8 ,
50- repeat : Infinity ,
51- ease : "linear" ,
52+ duration : 0.8 ,
53+ ease : "easeOut" ,
5254 } }
5355 />
5456 </ div >
55- </ div >
56-
57- < div className = "absolute top-[calc(50%-66px)] left-1/2 -translate-x-1/2 -translate-y-[calc(50%-33px)] flex flex-col gap-4 items-center justify-center" >
58- { /* 레벨업 텍스트 - 위로 바운스 */ }
59- < motion . img
60- src = { assetTextLevelup }
61- alt = "레벨업"
62- initial = { { y : 50 , opacity : 0 } }
63- animate = { { y : 0 , opacity : 1 } }
64- transition = { {
65- duration : 0.6 ,
66- type : "spring" ,
67- bounce : 0.6 ,
68- delay : 0.3 ,
69- } }
70- />
71-
72- { /* 뱃지 */ }
73- < motion . img
74- className = "w-[130px] h-[140px] z-10"
75- src = { assetBadge }
76- alt = "뱃지"
77- initial = { { scale : 0 , opacity : 0 } }
78- animate = { { scale : 1 , opacity : 1 } }
79- transition = { {
80- duration : 0.5 ,
81- type : "spring" ,
82- bounce : 0.4 ,
83- delay : 0.6 ,
84- } }
85- />
86- </ div >
87- </ Dialog . Content >
88- </ Dialog . Portal >
57+ </ Dialog . Content >
58+ </ Dialog . Portal >
59+ </ AnimatePresence >
8960 </ Dialog . Root >
9061 ) ;
9162} ;
0 commit comments