Skip to content

Commit 53402ac

Browse files
committed
feat: 로딩 애니메이션 및 페이드 인 효과 추가
1 parent 79b60e5 commit 53402ac

File tree

3 files changed

+89
-13
lines changed

3 files changed

+89
-13
lines changed

src/assets/app.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
@theme {
44
--color-bright: #dadacf;
5+
--animate-fadeIn: fadeIn 1s ease-in-out;
6+
7+
@keyframes fadeIn {
8+
from { opacity: 0; }
9+
to { opacity: 1; }
10+
}
511
}
612

713
@font-face {

src/components/MonitorBG.tsx

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
import {Canvas, useFrame, useThree} from "@react-three/fiber";
22
import GameBoy from "./GameBoy.tsx";
3-
import {CameraShake, ContactShadows, Float, Html} from "@react-three/drei";
3+
import {CameraShake, ContactShadows, Float, Html, useProgress} from "@react-three/drei";
44
import * as THREE from "three";
55
import {DoubleSide} from "three";
6-
import {useState} from "react";
6+
import {Suspense, useState} from "react";
77

88
const CAM_DISTANCE = 5;
99

1010
export default function MonitorBG() {
1111
return <div style={{position: "absolute", inset: 0}}>
12-
<Canvas eventPrefix="client" shadows dpr={[1, 2]} style={{width: '100%', height: '100%'}} camera={[0, 0, CAM_DISTANCE, {fov: 50}] as any}>
13-
<ambientLight color={"#dadacf"} intensity={1.2}/>
14-
<Float rotationIntensity={1.5} floatIntensity={1.5} speed={3}>
15-
<GameBoy position={[-1, -1, -.5]} rotation={[.2, 0, 0]} scale={.25}/>
16-
<Html occlude={"raycast"} transform castShadow receiveShadow scale={.25} position={[1, .3, 0]} rotation={[.2, 0, 0]}
17-
material={<meshStandardMaterial side={DoubleSide} opacity={.1}/>}>
18-
<Card/>
19-
</Html>
20-
</Float>
21-
<ContactShadows position={[0, -1.2, 0]} opacity={1} scale={10} blur={1} far={10} resolution={256} color="#000000"/>
22-
<Rig/>
12+
<Canvas className={"animate-fadeIn"} eventPrefix="client" shadows dpr={[1, 2]} style={{width: '100%', height: '100%'}} camera={[0, 0, CAM_DISTANCE, {fov: 50}] as any}>
13+
<Suspense fallback={<Loader/>}>
14+
<ambientLight color={"#dadacf"} intensity={1.2}/>
15+
<Float rotationIntensity={1.5} floatIntensity={1.5} speed={3}>
16+
<GameBoy position={[-1, -1, -.5]} rotation={[.2, 0, 0]} scale={.25}/>
17+
<Html occlude={"raycast"} transform castShadow receiveShadow scale={.25} position={[1, .3, 0]} rotation={[.2, 0, 0]}
18+
material={<meshStandardMaterial side={DoubleSide} opacity={.1}/>}>
19+
<Card/>
20+
</Html>
21+
</Float>
22+
<ContactShadows position={[0, -1.2, 0]} opacity={1} scale={10} blur={1} far={10} resolution={256} color="#000000"/>
23+
<Rig/>
24+
</Suspense>
2325
</Canvas>
2426
</div>
2527
}
@@ -90,4 +92,30 @@ const Tag = (
9092
<img src={icon} alt="" width={16}/>
9193
{text}
9294
</div>
95+
}
96+
97+
function Loader() {
98+
const { progress } = useProgress()
99+
return <Html center>
100+
<div
101+
className="mx-auto w-[500px] h-[400px] bg-gray-950 rounded-xl overflow-hidden drop-shadow-xl"
102+
>
103+
<div className="bg-[#333] flex items-center p-[5px] text-whitec relative">
104+
<div className="flex absolute left-3">
105+
<span className="h-3.5 w-3.5 bg-[#ff5b50] rounded-xl mr-2"></span>
106+
<span className="h-3.5 w-3.5 bg-[#fbbc33] rounded-xl mr-2"></span>
107+
<span className="h-3.5 w-3.5 bg-[#21c940] rounded-xl"></span>
108+
</div>
109+
<div className="flex-1 text-center text-white">status</div>
110+
</div>
111+
<div className="p-2.5 text-bright text-xl">
112+
<div>
113+
<span className="mr-2">{progress}% loaded</span>
114+
<span className="animate-[ping_1.5s_0.5s_ease-in-out_infinite]">.</span>
115+
<span className="animate-[ping_1.5s_0.7s_ease-in-out_infinite]">.</span>
116+
<span className="animate-[ping_1.5s_0.9s_ease-in-out_infinite]">.</span>
117+
</div>
118+
</div>
119+
</div>
120+
</Html>
93121
}

src/pages/index.astro

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,52 @@ import Layout from '../layouts/Layout.astro';
1010
<div class="w-full h-full relative">
1111
<MonitorBG client:only="react">
1212
<Fragment slot="fallback">
13+
<div class="w-full h-full text-bright text-3xl flex flex-col gap-2 justify-center items-center">
14+
<div class="loader">
15+
<span class="bar"></span>
16+
<span class="bar"></span>
17+
<span class="bar"></span>
18+
</div>
19+
Loading 3D...
20+
</div>
1321
</Fragment>
1422
</MonitorBG>
1523
</div>
1624
</Layout>
1725

1826
<style>
27+
.loader {
28+
display: flex;
29+
align-items: center;
30+
}
31+
32+
.bar {
33+
display: inline-block;
34+
width: 3px;
35+
height: 20px;
36+
background-color: rgba(255, 255, 255, .5);
37+
border-radius: 10px;
38+
animation: scale-up4 1s linear infinite;
39+
}
40+
41+
.bar:nth-child(2) {
42+
height: 35px;
43+
margin: 0 5px;
44+
animation-delay: .25s;
45+
}
46+
47+
.bar:nth-child(3) {
48+
animation-delay: .5s;
49+
}
50+
51+
@keyframes scale-up4 {
52+
20% {
53+
background-color: #ffff;
54+
transform: scaleY(1.5);
55+
}
56+
57+
40% {
58+
transform: scaleY(1);
59+
}
60+
}
1961
</style>

0 commit comments

Comments
 (0)