Skip to content

Commit 8b26322

Browse files
committed
feat: optimize page loading with dynamic loading screen
1 parent 77f24ef commit 8b26322

File tree

4 files changed

+168
-8
lines changed

4 files changed

+168
-8
lines changed

src/layouts/MainLayout.astro

Lines changed: 165 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,30 @@ import logo from '../assets/logo.svg';
66
interface Props {
77
title: string;
88
description?: string;
9+
pageType?: 'index' | 'members' | 'honors';
910
}
1011
11-
const { title, description = "Official website of N0wayBack Team" } = Astro.props;
12+
const {
13+
title,
14+
description = "Official website of N0wayBack Team",
15+
pageType = 'index'
16+
} = Astro.props as Props;
17+
18+
// 根据页面类型设置不同的加载消息和速度
19+
const loadingMessages: Record<string, string[]> = {
20+
index: ['SYSTEM INITIALIZATION...', 'LOADING CORE MODULES...', 'ESTABLISHING SECURE CONNECTION...', 'SYSTEM READY'],
21+
members: ['LOADING TEAM DATA...', 'DECRYPTING PROFILES...', 'TEAM READY'],
22+
honors: ['RETRIEVING ACHIEVEMENTS...', 'COMPILING RECORDS...', 'DATA READY']
23+
};
24+
25+
const loadingSpeed: Record<string, number> = {
26+
index: 200, // 较慢
27+
members: 100, // 较快
28+
honors: 80 // 最快
29+
};
30+
31+
const messages = loadingMessages[pageType];
32+
const speed = loadingSpeed[pageType];
1233
---
1334

1435
<!DOCTYPE html>
@@ -37,15 +58,46 @@ const { title, description = "Official website of N0wayBack Team" } = Astro.prop
3758
localStorage.setItem('theme', theme);
3859
}
3960
</script>
61+
62+
<!-- 将页面类型和加载消息传递给JavaScript -->
63+
<script define:vars={{ pageType, messages, speed }}>
64+
// 将变量存储在window对象上,以便在DOMContentLoaded事件中使用
65+
window.pageConfig = {
66+
pageType: pageType,
67+
messages: messages,
68+
speed: speed
69+
};
70+
</script>
4071
</head>
4172
<body class="bg-primary-light dark:bg-primary-dark text-light-light dark:text-light-dark min-h-screen terminal-boot">
73+
<!-- 加载动画 -->
74+
<div id="loading-screen" class="loading-screen">
75+
<div class="loading-container">
76+
<div class="loading-logo">N0wayBack</div>
77+
<div class="loading-bar-container">
78+
<div class="loading-bar"></div>
79+
</div>
80+
<div class="loading-text">{messages[0]}</div>
81+
</div>
82+
</div>
83+
4284
<Navbar />
4385
<main class="fade-in">
4486
<slot />
4587
</main>
4688
<Footer />
4789

4890
<script>
91+
declare global {
92+
interface Window {
93+
pageConfig?: {
94+
pageType: string;
95+
messages: string[];
96+
speed: number;
97+
}
98+
}
99+
}
100+
49101
document.addEventListener('DOMContentLoaded', () => {
50102
// 从 localStorage 中获取用户的主题选择
51103
const currentTheme = localStorage.getItem('theme');
@@ -61,10 +113,51 @@ const { title, description = "Official website of N0wayBack Team" } = Astro.prop
61113
localStorage.setItem('theme', 'dark');
62114
}
63115

64-
// 添加终端启动效果
65-
setTimeout(() => {
66-
document.body.classList.add('terminal-booted');
67-
}, 500);
116+
// 获取页面配置
117+
const { messages, speed } = window.pageConfig || {
118+
messages: ['LOADING...', 'READY'],
119+
speed: 200
120+
};
121+
122+
// 增强的终端启动效果
123+
const loadingScreen = document.getElementById('loading-screen');
124+
const loadingBar = document.querySelector('.loading-bar') as HTMLElement;
125+
const loadingText = document.querySelector('.loading-text') as HTMLElement;
126+
127+
// 确保元素存在
128+
if (loadingScreen && loadingBar && loadingText) {
129+
// 模拟加载进度
130+
let progress = 0;
131+
let messageIndex = 0;
132+
const interval = setInterval(() => {
133+
progress += Math.random() * 15;
134+
if (progress >= 100) {
135+
progress = 100;
136+
clearInterval(interval);
137+
138+
// 显示完成消息
139+
loadingText.textContent = messages[messages.length - 1];
140+
141+
// 延迟后隐藏加载屏幕
142+
setTimeout(() => {
143+
loadingScreen.classList.add('loaded');
144+
document.body.classList.add('terminal-booted');
145+
}, 500);
146+
}
147+
148+
// 更新加载条
149+
loadingBar.style.width = `${progress}%`;
150+
151+
// 更新加载消息
152+
if (progress > 30 && progress < 60 && messageIndex === 0) {
153+
messageIndex = 1;
154+
loadingText.textContent = messages[messageIndex];
155+
} else if (progress >= 60 && progress < 90 && messageIndex === 1 && messages.length > 2) {
156+
messageIndex = 2;
157+
loadingText.textContent = messages[messageIndex];
158+
}
159+
}, speed);
160+
}
68161
});
69162
</script>
70163
</body>
@@ -129,4 +222,71 @@ const { title, description = "Official website of N0wayBack Team" } = Astro.prop
129222
from { opacity: 0; transform: translateY(10px); }
130223
to { opacity: 1; transform: translateY(0); }
131224
}
225+
226+
/* 加载动画 */
227+
.loading-screen {
228+
position: fixed;
229+
top: 0;
230+
left: 0;
231+
width: 100%;
232+
height: 100%;
233+
background: #000;
234+
display: flex;
235+
justify-content: center;
236+
align-items: center;
237+
z-index: 9999;
238+
transition: opacity 0.5s ease;
239+
}
240+
241+
.loading-container {
242+
text-align: center;
243+
width: 300px;
244+
padding: 20px;
245+
border: 1px solid rgba(0, 158, 127, 0.5);
246+
border-radius: 4px;
247+
background-color: rgba(0, 0, 0, 0.8);
248+
box-shadow: 0 0 20px rgba(0, 158, 127, 0.3);
249+
}
250+
251+
.loading-logo {
252+
font-family: 'Fira Code', monospace;
253+
font-size: 28px;
254+
font-weight: bold;
255+
color: #fff;
256+
margin-bottom: 20px;
257+
text-shadow: 0 0 10px rgba(0, 158, 127, 0.7);
258+
letter-spacing: 2px;
259+
}
260+
261+
.loading-bar-container {
262+
width: 100%;
263+
height: 10px;
264+
background: #111;
265+
border-radius: 5px;
266+
margin: 0 auto;
267+
margin-bottom: 20px;
268+
overflow: hidden;
269+
border: 1px solid rgba(0, 158, 127, 0.3);
270+
}
271+
272+
.loading-bar {
273+
width: 0%;
274+
height: 100%;
275+
background: linear-gradient(90deg, #009e7f, #00d6a4);
276+
border-radius: 5px;
277+
transition: width 0.2s ease;
278+
box-shadow: 0 0 10px rgba(0, 158, 127, 0.7);
279+
}
280+
281+
.loading-text {
282+
font-family: 'Fira Code', monospace;
283+
font-size: 16px;
284+
color: #fff;
285+
letter-spacing: 1px;
286+
}
287+
288+
.loaded {
289+
opacity: 0;
290+
pointer-events: none;
291+
}
132292
</style>

src/pages/honors.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const honorsByYear = sortedHonors.reduce((acc, honor) => {
1919
const years = Object.keys(honorsByYear).map(Number).sort((a, b) => b - a);
2020
---
2121

22-
<MainLayout title="Honors">
22+
<MainLayout title="Honors & Achievements" pageType="honors">
2323
<div class="cyberpunk-grid"></div>
2424

2525
<section class="py-8 md:py-16">

src/pages/index.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import logo from '../assets/logo.svg';
44
import logoOrigin from '../assets/logo-origin.webp';
55
---
66

7-
<MainLayout title="Home">
7+
<MainLayout title="Home" pageType="index">
88
<div class="cyberpunk-grid"></div>
99

1010
<section class="py-8 md:py-16 min-h-[80vh] flex items-center">

src/pages/members.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ if (pioneerMembers.length === 0) {
2121
}
2222
---
2323

24-
<MainLayout title="Team Members">
24+
<MainLayout title="Team Members" pageType="members">
2525
<div class="cyberpunk-grid"></div>
2626

2727
<section class="py-8 md:py-16">

0 commit comments

Comments
 (0)