Skip to content

Commit 71958b3

Browse files
committed
feat: add simple 3d motion
1 parent be1d5cd commit 71958b3

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

src/app/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export default function Home() {
6666
<Cards.TextCard />
6767
<Cards.BlockCard />
6868
<Cards.BlocksCard />
69+
<Cards.ThreeDimension />
6970
<Cards.PresetCard />
7071
</PageCardContainer>
7172
</>

src/components/main-page/PageContainer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ export default function PageContainer({
2525
);
2626
}
2727

28-
const Container = styled.div`
28+
const Container = styled.button`
2929
position: relative;
3030
width: 20rem;
3131
height: 15rem;
3232
background-color: #f5f5f5;
33+
border: none;
3334
border-radius: 1rem;
3435
overflow: hidden;
3536
cursor: pointer;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { useEffect, useRef, useState } from "react";
2+
import gsap from "gsap";
3+
import styled from "@emotion/styled";
4+
import PageContainer from "./PageContainer";
5+
6+
export default function ThreeDimension() {
7+
const [isHover, setIsHover] = useState(false);
8+
const isMountRef = useRef(false);
9+
const cube1Ref = useRef<HTMLDivElement>(null);
10+
const cube2Ref = useRef<HTMLDivElement>(null);
11+
12+
useEffect(() => {
13+
if (!isMountRef.current) {
14+
isMountRef.current = true;
15+
gsap.set(cube2Ref.current, {
16+
rotateY: "-90deg",
17+
x: "100px",
18+
opacity: 1,
19+
});
20+
gsap.set(cube1Ref.current, { opacity: 1 });
21+
return;
22+
}
23+
24+
if (isHover) {
25+
gsap.to(cube1Ref.current, {
26+
rotateY: "90deg",
27+
x: "-100px",
28+
duration: 0.5,
29+
});
30+
gsap.fromTo(
31+
cube2Ref.current,
32+
{
33+
rotateY: "-90deg",
34+
x: "100px",
35+
duration: 0,
36+
},
37+
{
38+
rotateY: "0deg",
39+
x: "0",
40+
duration: 0.5,
41+
}
42+
);
43+
} else {
44+
gsap.to(cube2Ref.current, {
45+
rotateY: "-90deg",
46+
x: "100px",
47+
duration: 0.5,
48+
});
49+
gsap.fromTo(
50+
cube1Ref.current,
51+
{
52+
rotateY: "90deg",
53+
x: "-100px",
54+
duration: 0,
55+
},
56+
{
57+
rotateY: "0deg",
58+
x: "0",
59+
duration: 0.5,
60+
}
61+
);
62+
}
63+
}, [isHover]);
64+
65+
return (
66+
<PageContainer
67+
mouseEnterEvent={() => setIsHover(true)}
68+
mouseLeaveEvent={() => setIsHover(false)}
69+
navigateTo="3d"
70+
>
71+
<Container>
72+
<Cube1 className="cube-1" ref={cube1Ref} />
73+
<Cube2 className="cube-2" ref={cube2Ref} />
74+
</Container>
75+
</PageContainer>
76+
);
77+
}
78+
79+
const Container = styled.div`
80+
width: 100%;
81+
height: 100%;
82+
display: flex;
83+
justify-content: center;
84+
align-items: center;
85+
`;
86+
87+
const Cube1 = styled.div`
88+
position: absolute;
89+
width: 10rem;
90+
height: 10rem;
91+
background-color: #cccccc;
92+
`;
93+
94+
const Cube2 = styled.div<{ isHover?: boolean }>`
95+
position: absolute;
96+
width: 10rem;
97+
height: 10rem;
98+
background-color: #777777;
99+
`;

src/components/main-page/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ import BlockCard from "./BlockCard";
22
import BlocksCard from "./BlocksCard";
33
import TextCard from "./TextCard";
44
import PresetCard from "./PresetCard";
5+
import ThreeDimension from "./ThreeDimension";
56

6-
export { BlockCard, BlocksCard, TextCard, PresetCard };
7+
export { BlockCard, BlocksCard, TextCard, PresetCard, ThreeDimension };

0 commit comments

Comments
 (0)