@@ -11,75 +11,90 @@ import {
11
11
Separator ,
12
12
TypographyMuted ,
13
13
} from 'ui/components' ;
14
+ import {
15
+ MotionValue ,
16
+ animate ,
17
+ motion ,
18
+ useMotionTemplate ,
19
+ useMotionValue ,
20
+ useTransform ,
21
+ } from 'framer-motion' ;
22
+ import { useCallback , MouseEvent , useRef } from 'react' ;
14
23
15
24
export default function CardDemo ( ) {
16
- const IMAGE =
17
- 'https://store.storeimages.cdn-apple.com/8756/as-images.apple.com/is/mbp-digitalmat-gallery-2-202206_GEO_KR?wid=364&hei=333&fmt=png-alpha&.v=1665427482788' ;
25
+ const cardRef = useRef < HTMLDivElement > ( null ) ;
26
+ const mouseX = useMotionValue ( 0 ) ;
27
+ const mouseY = useMotionValue ( 0 ) ;
28
+ const depth = 45 ;
29
+
30
+ const handleMouseMove = useCallback (
31
+ ( { currentTarget, clientX, clientY } : MouseEvent ) => {
32
+ let { left, top } = currentTarget . getBoundingClientRect ( ) ;
33
+
34
+ mouseX . set ( clientX - left ) ;
35
+ mouseY . set ( clientY - top ) ;
36
+ } ,
37
+ [ mouseX , mouseY ]
38
+ ) ;
39
+
40
+ let rotateX = useTransform < number , number > ( mouseX , ( newMouseX ) => {
41
+ if ( ! cardRef . current ) return 0 ;
42
+
43
+ const rect = cardRef . current . getBoundingClientRect ( ) ;
44
+ const newRotateX = newMouseX - rect . left - rect . height / 2 ;
45
+
46
+ return - newRotateX / depth ;
47
+ } ) ;
48
+ let rotateY = useTransform < number , number > ( mouseY , ( newMouseY ) => {
49
+ if ( ! cardRef . current ) return 0 ;
50
+
51
+ const rect = cardRef . current . getBoundingClientRect ( ) ;
52
+ const newRotateY = newMouseY - rect . top - rect . width / 2 ;
53
+
54
+ return newRotateY / depth ;
55
+ } ) ;
18
56
19
57
return (
20
- < Card className = 'flex h-full w-full justify-evenly' >
21
- < Card className = 'select-none rounded-none' >
22
- < Image
23
- className = 'h-full flex-1 bg-cover'
24
- width = { 300 }
25
- height = { 500 }
26
- src = { IMAGE }
27
- alt = 'MacBook pro 13'
28
- />
29
- </ Card >
30
- < Card className = 'flex-1 select-none rounded-none' >
31
- < CardHeader >
32
- < CardTitle > MacBook Pro 13</ CardTitle >
33
- < div className = 'flex items-baseline justify-between' >
34
- < CardDescription > ₩1,790,000부터</ CardDescription >
35
- < Button
36
- className = 'pointer-events-none rounded-3xl bg-blue-500'
37
- size = 'sm'
38
- >
39
- 구입하기
40
- </ Button >
41
- </ div >
42
- </ CardHeader >
43
- < CardContent className = 'flex flex-col gap-y-2' >
44
- < div className = 'flex items-center gap-x-2' >
45
- < Icons . monitor size = { 30 } />
46
- < TypographyMuted className = 'overflow-hidden text-ellipsis text-xs' >
47
- 차세대 Apple M2 칩과 전문가급 성능을 유지해주는 액티브 쿨링
48
- 시스템으로 더 많은 일을 더 빠르게 처리
49
- </ TypographyMuted >
50
- </ div >
51
- < Separator />
52
- < div className = 'flex items-center gap-x-2' >
53
- < Icons . batteryFull size = { 30 } />
54
- < TypographyMuted className = 'overflow-hidden text-ellipsis text-xs' >
55
- 하루 종일 쓰고도 밤 늦게까지 너끈한 최대 20시간의 배터리 사용
56
- 시간각주¹
57
- </ TypographyMuted >
58
- </ div >
59
- < Separator />
60
- < div className = 'flex items-center gap-x-2' >
61
- < Icons . diagonal size = { 30 } />
62
- < TypographyMuted className = 'overflow-hidden text-ellipsis text-xs' >
63
- 생생한 색상과 놀라운 디테일을 보여주는 500 니트 밝기의 Retina
64
- 디스플레이
65
- </ TypographyMuted >
66
- </ div >
67
- < Separator />
68
- < div className = 'flex items-center gap-x-2' >
69
- < Icons . plugZap size = { 30 } />
70
- < TypographyMuted className = 'overflow-hidden text-ellipsis text-xs' >
71
- 고속 액세서리에 연결하고 전원을 공급해주는 Thunderbolt 포트 2개
72
- </ TypographyMuted >
73
- </ div >
74
- < Separator />
58
+ // <div className='flex h-[500px] w-full items-center justify-center border-2 bg-gray-600'>
59
+ // <motion.div
60
+ // onMouseMove={handleMouseMove}
61
+ // ref={cardRef}
62
+ // className=' h-[80%] w-[80%] border-2 bg-white backdrop-blur-xl'
63
+ // style={{ rotateX, rotateY }}
64
+ // >
65
+ // 3D Card
66
+ // </motion.div>
67
+ // </div>
68
+ < Card
69
+ className = 'group relative w-full max-w-md rounded-xl border border-white/10 bg-gray-900 px-8 py-16 shadow-2xl shadow-gray-900'
70
+ onMouseMove = { handleMouseMove }
71
+ >
72
+ < motion . div
73
+ className = 'pointer-events-none absolute -inset-px rounded-xl border-2 opacity-0 transition duration-300 group-hover:opacity-100'
74
+ style = { {
75
+ background : useMotionTemplate `
76
+ radial-gradient(
77
+ 650px circle at ${ mouseX } px ${ mouseY } px,
78
+ rgba(14, 165, 233, 0.15),
79
+ transparent 90%
80
+ )
81
+ ` ,
82
+ } }
83
+ />
84
+ < CardHeader >
85
+ < CardTitle className = 'text-5xl font-bold tracking-tight text-white' >
86
+ Card
87
+ </ CardTitle >
88
+ < CardDescription className = 'text-base font-semibold leading-7 text-sky-500' >
89
+ Component
90
+ </ CardDescription >
91
+ < CardContent className = 'mt-2 flex items-center gap-x-2' >
92
+ < p className = 'mt-6 text-base leading-7 text-gray-300' >
93
+ Lorem ipsum dolor sit amet consectetur adipisicing elit, facilis
94
+ illum eum ullam nostrum atque quam.
95
+ </ p >
75
96
</ CardContent >
76
- < CardFooter className = 'flex cursor-pointer select-none items-center gap-x-1 ' >
77
- < TypographyMuted className = 'text-blue-500' >
78
- MacBook Pro 13 더 살펴보기
79
- </ TypographyMuted >
80
- < Icons . chevronRight className = 'text-blue-500' size = { 15 } />
81
- </ CardFooter >
82
- </ Card >
97
+ </ CardHeader >
83
98
</ Card >
84
99
) ;
85
100
}
0 commit comments