Skip to content

Commit dcd88d3

Browse files
authored
refactor: Change DotLottie To Custom loading component (#45)
- Animated progress bars that fill sequentially - Auto-resetting animation loop every 10 steps - Clean grid layout with proper spacing
1 parent 06d95f1 commit dcd88d3

File tree

5 files changed

+35
-23
lines changed

5 files changed

+35
-23
lines changed

client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"fix": "pnpm format && pnpm lint:fix",
1717
"storybook": "storybook dev -p 6006",
1818
"build-storybook": "storybook build",
19-
"lighthouse": "playwright test --project=lighthouse"
19+
"lighthouse": "pnpm build && playwright test --project=lighthouse"
2020
},
2121
"dependencies": {
2222
"@lottiefiles/dotlottie-react": "^0.10.1",

client/src/components/ui/BackgroundImage.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useRef, useState } from 'react';
1+
import { useState } from 'react';
22
import tiny from '@/assets/background-tiny.png';
33
import { CDN } from '@/constants/cdn';
44
import { cn } from '@/utils/cn';
@@ -9,14 +9,6 @@ interface BackgroundImageProps {
99

1010
const BackgroundImage = ({ className }: BackgroundImageProps) => {
1111
const [isLoaded, setIsLoaded] = useState(false);
12-
const imgRef = useRef<HTMLImageElement>(null);
13-
14-
useEffect(() => {
15-
const img = imgRef.current;
16-
if (img) {
17-
img.onload = () => setIsLoaded(true);
18-
}
19-
}, [imgRef.current]);
2012

2113
return (
2214
<>
@@ -40,7 +32,7 @@ const BackgroundImage = ({ className }: BackgroundImageProps) => {
4032
'h-full w-full object-cover transition-opacity duration-300',
4133
isLoaded ? 'opacity-100' : 'opacity-0',
4234
)}
43-
ref={imgRef}
35+
onLoad={() => setIsLoaded(true)}
4436
loading="lazy"
4537
decoding="async"
4638
/>
Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,34 @@
1-
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
2-
import loading from '@/assets/lottie/loading.lottie';
1+
import { useEffect, useState } from 'react';
32

43
export const Loading = () => {
4+
const [barCount, setBarCount] = useState(1);
5+
6+
useEffect(() => {
7+
const timer = setInterval(() => {
8+
setBarCount((prevCount) => (prevCount >= 10 ? 1 : prevCount + 1));
9+
}, 500);
10+
11+
return () => clearInterval(timer);
12+
}, []);
13+
514
return (
6-
<div className="flex h-screen w-full items-center justify-center">
7-
<DotLottieReact src={loading} loop autoplay className="h-96 w-96" />
15+
<div className="relative min-h-screen min-w-80 bg-violet-950 bg-fixed antialiased">
16+
<div className="flex h-screen w-full flex-col items-center justify-center gap-2">
17+
<span className="text-3xl text-violet-300">LOADING...</span>
18+
<div className="relative h-14 w-full max-w-64 border-8 border-violet-300">
19+
<div className="absolute -left-2 -top-2 h-2 w-2 bg-slate-950" />
20+
<div className="absolute -right-2 -top-2 h-2 w-2 bg-slate-950" />
21+
<div className="absolute -bottom-2 -left-2 h-2 w-2 bg-slate-950" />
22+
<div className="absolute -bottom-2 -right-2 h-2 w-2 bg-slate-950" />
23+
<div className="grid h-full grid-cols-10 gap-2 p-2">
24+
{Array.from({ length: barCount }).map((_, index) => (
25+
<div key={index} className="relative h-full bg-violet-300">
26+
<div className="absolute bottom-0 h-1/2 w-full bg-violet-500" />
27+
</div>
28+
))}
29+
</div>
30+
</div>
31+
</div>
832
</div>
933
);
1034
};

client/src/layouts/GameLayout.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
21
import { Outlet } from 'react-router-dom';
3-
import loading from '@/assets/lottie/loading.lottie';
42
import { ChatContatiner } from '@/components/chat/ChatContatiner';
53
import { NavigationModal } from '@/components/modal/NavigationModal';
64
import { PlayerCardList } from '@/components/player/PlayerCardList';
75
import BackgroundImage from '@/components/ui/BackgroundImage';
6+
import { Loading } from '@/components/ui/Loading';
87
import { useGameSocket } from '@/hooks/socket/useGameSocket';
98
import BrowserNavigationGuard from '@/layouts/BrowserNavigationGuard';
109
import GameHeader from '@/layouts/GameHeader';
@@ -19,11 +18,7 @@ const GameLayout = () => {
1918

2019
// 연결 상태에 따른 로딩 표시
2120
if (!isConnected) {
22-
return (
23-
<div className="flex h-screen w-full items-center justify-center">
24-
<DotLottieReact src={loading} loop autoplay className="h-96 w-96" />
25-
</div>
26-
);
21+
return <Loading />;
2722
}
2823

2924
return (

client/src/main.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { StrictMode, Suspense } from 'react';
22
import { createRoot } from 'react-dom/client';
33
import '@/index.css';
44
import { RouterProvider } from 'react-router-dom';
5+
import { Loading } from './components/ui/Loading';
56
import App from '@/App.tsx';
67
import { router } from '@/routes';
78

89
createRoot(document.getElementById('root')!).render(
910
<StrictMode>
1011
<App>
11-
<Suspense fallback={null}>
12+
<Suspense fallback={<Loading />}>
1213
<RouterProvider router={router} future={{ v7_startTransition: true }} />
1314
</Suspense>
1415
</App>

0 commit comments

Comments
 (0)