11import { useState , useRef , useEffect } from 'react' ;
2- import { Link } from 'react-router' ;
32import { twMerge } from 'tailwind-merge' ;
43
54import envelope from '@/assets/images/closed-letter.png' ;
6- import envelopeTop from '@/assets/images/envelope-pink-back-top.png' ;
5+ // import envelopeTop from '@/assets/images/envelope-pink-back-top.png';
76import envelopeFront from '@/assets/images/opened-letter-front.png' ;
87
9- export default function UserInteraction ( ) {
8+ export default function UserInteraction ( {
9+ setIsAnimationOver,
10+ } : {
11+ setIsAnimationOver : React . Dispatch < React . SetStateAction < boolean > > ;
12+ } ) {
1013 const imgRef = useRef < HTMLImageElement > ( null ) ;
11- const [ imgPos , setImgPos ] = useState < { top : number ; width : number } > ( { top : 0 , width : 0 } ) ;
14+ const [ imgPos , setImgPos ] = useState < {
15+ top : number ;
16+ width : number ;
17+ height : number ;
18+ left : number ;
19+ } > ( {
20+ top : 0 ,
21+ width : 0 ,
22+ height : 0 ,
23+ left : 0 ,
24+ } ) ;
1225 const [ imgToBottom , setImgToBottom ] = useState < boolean > ( false ) ;
1326
1427 const [ startAnimation , setStartAnimation ] = useState < boolean > ( false ) ;
15- const [ openAnimation , setOpenAnimation ] = useState < boolean > ( false ) ;
28+ // const [openAnimation, setOpenAnimation] = useState<boolean>(false);
1629 const [ letterOutAnimation , setLetterOutAnimation ] = useState < boolean > ( false ) ;
1730 const [ envelopeOut , setEnvelopeOut ] = useState < boolean > ( false ) ;
1831 const [ finishAnimation , setFinishAnimation ] = useState < boolean > ( false ) ;
1932
2033 const handleLetterClick = ( ) => {
2134 if ( imgRef . current ) {
2235 const rect = imgRef . current . getBoundingClientRect ( ) ;
23- setImgPos ( { top : rect . top , width : rect . width } ) ;
36+ setImgPos ( { top : rect . top , width : rect . width , height : rect . height , left : rect . left } ) ;
2437 }
2538 setStartAnimation ( true ) ;
2639 setTimeout ( ( ) => {
@@ -31,18 +44,18 @@ export default function UserInteraction() {
3144 useEffect ( ( ) => {
3245 if ( imgToBottom ) {
3346 setTimeout ( ( ) => {
34- setOpenAnimation ( true ) ;
47+ setLetterOutAnimation ( true ) ;
3548 } , 1000 ) ;
3649 }
3750 } , [ imgToBottom ] ) ;
3851
39- useEffect ( ( ) => {
40- if ( openAnimation ) {
41- setTimeout ( ( ) => {
42- setLetterOutAnimation ( true ) ;
43- } , 2000 ) ;
44- }
45- } , [ openAnimation ] ) ;
52+ // useEffect(() => {
53+ // if (openAnimation) {
54+ // setTimeout(() => {
55+ // setLetterOutAnimation(true);
56+ // }, 2000);
57+ // }
58+ // }, [openAnimation]);
4659
4760 useEffect ( ( ) => {
4861 if ( letterOutAnimation ) {
@@ -56,9 +69,18 @@ export default function UserInteraction() {
5669 if ( envelopeOut ) {
5770 setTimeout ( ( ) => {
5871 setFinishAnimation ( true ) ;
59- } , 2000 ) ;
72+ } , 1000 ) ;
6073 }
6174 } , [ envelopeOut ] ) ;
75+
76+ useEffect ( ( ) => {
77+ if ( finishAnimation ) {
78+ setTimeout ( ( ) => {
79+ setIsAnimationOver ( true ) ;
80+ } , 2000 ) ;
81+ }
82+ } , [ finishAnimation ] ) ;
83+
6284 if ( startAnimation === false ) {
6385 return (
6486 < >
@@ -80,67 +102,78 @@ export default function UserInteraction() {
80102 ) ;
81103 } else {
82104 return (
83- < >
105+ < div className = "relative h-[calc(100vh-110px)] w-full overflow-hidden" >
84106 < img
85107 src = { envelopeFront }
86- alt = "분홍색 편지지 "
108+ alt = ""
87109 className = { twMerge (
88- `z-30 mx-10 h-auto rounded transition-transform duration-1000 ease-in-out ` ,
89- imgToBottom && 'translate-y-full ',
110+ `transform-translation z-30 mx-10 h-auto rounded` ,
111+ imgToBottom && ! envelopeOut && 'animate-envelopeSink ',
90112 envelopeOut && 'animate-envelopeOut' ,
91113 ) }
92114 style = { {
93- top : `${ imgPos . top } px` ,
115+ top : `calc( ${ imgPos . top } px - 5rem) ` ,
94116 position : 'absolute' ,
95117 width : `${ imgPos . width } px` ,
118+ left : '0px' ,
96119 } }
97120 />
98- { letterOutAnimation && (
99- < div
100- className = "animate-expandScale to-gray-5 z-20 max-w-[600px] rounded-lg bg-linear-to-b from-white"
101- style = { {
102- width : `${ imgPos . width - imgPos . width * 0.1 } px` ,
103- bottom : `${ imgPos . top - 0.7 * imgPos . top } px` ,
104- top : `${ imgPos . top - 0.5 * imgPos . top } px` ,
105- position : 'absolute' ,
106- } }
107- > </ div >
108- ) }
109- { openAnimation && (
121+ { /* {openAnimation && (
110122 <img
111123 src={envelopeTop}
112124 alt=""
113125 className={twMerge(
114- `z-10 mx-10 h-auto rounded transition-transform duration-1000 ease-in-out` ,
115- imgToBottom && 'translate-y-full' ,
116- openAnimation && 'animate-openEnvelope' ,
126+ `z-10 mx-10 h-auto rounded`,
127+ openAnimation && !envelopeOut && 'animate-openEnvelope',
117128 envelopeOut && 'animate-envelopeOut',
118129 )}
119130 style={{
120- top : `${ imgPos . top } px` ,
131+ bottom : `calc(${sinkRefTop .top}px - 7.5rem) `,
121132 position: 'absolute',
122133 width: `${imgPos.width}px`,
123- transformOrigin : 'bottom ' ,
134+ left : '0px ',
124135 }}
125136 />
126- ) }
137+ )} */ }
127138 < img
128139 src = { envelope }
129140 alt = "분홍색 편지지"
141+ // ref={sinkRef}
142+ // onAnimationEnd={(e) => {
143+ // if (e.animationName === 'envelopeSink') {
144+ // const rect = sinkRef.current?.getBoundingClientRect();
145+ // if (rect?.top) setSinkRefTop({ top: rect?.top });
146+ // console.log('Animation ended. boundingRect top:', rect?.top);
147+ // }
148+ // }}
130149 className = { twMerge (
131- `z-0 mx-10 h-auto rounded transition-transform duration-1000 ease-in-out ` ,
132- imgToBottom && 'translate-y-full ',
150+ `z-0 mx-10 h-auto rounded` ,
151+ imgToBottom && ! envelopeOut && 'animate-envelopeSink ',
133152 envelopeOut && 'animate-envelopeOut' ,
134153 ) }
135154 style = { {
136- top : `${ imgPos . top } px` ,
155+ top : `calc( ${ imgPos . top } px - 5rem) ` ,
137156 position : 'absolute' ,
138157 width : `${ imgPos . width } px` ,
158+ left : '0px' ,
139159 } }
140160 />
141- { /* TODO: 편지지 링크 */ }
142- { finishAnimation && < Link to = { '/' } > </ Link > }
143- </ >
161+ { letterOutAnimation && (
162+ < div
163+ className = { twMerge (
164+ 'letter-gradient z-20 max-w-[600px] rounded-lg' ,
165+ finishAnimation ? 'animate-fadeOut' : 'animate-expandScale' ,
166+ ) }
167+ style = { {
168+ width : `${ imgPos . width - imgPos . width * 0.1 } px` ,
169+ bottom : `${ 0.9 * imgPos . height } px` ,
170+ top : `${ imgPos . top - 0.7 * imgPos . top } px` ,
171+ position : 'absolute' ,
172+ left : `58px` ,
173+ } }
174+ > </ div >
175+ ) }
176+ </ div >
144177 ) ;
145178 }
146179}
0 commit comments