Skip to content

Commit 0920281

Browse files
committed
加载动画优化
1 parent 53fb4ef commit 0920281

File tree

3 files changed

+148
-99
lines changed

3 files changed

+148
-99
lines changed
Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
package love.forte.simbot.codegen
22

33
import androidx.compose.animation.AnimatedContent
4+
import androidx.compose.animation.AnimatedVisibility
45
import androidx.compose.foundation.layout.*
56
import androidx.compose.material3.*
67
import androidx.compose.runtime.*
78
import androidx.compose.ui.Alignment
89
import androidx.compose.ui.Modifier
9-
import androidx.compose.ui.graphics.Color
1010
import androidx.compose.ui.text.font.FontFamily
1111
import androidx.compose.ui.unit.dp
1212
import kotlinx.browser.localStorage
1313
import love.forte.simbot.codegen.gen.view.GradleSettingsView
1414
import org.jetbrains.compose.resources.ExperimentalResourceApi
1515
import org.jetbrains.compose.resources.preloadFont
16-
import simbot_codegen.composeapp.generated.resources.LXGWNeoXiHeiScreen
17-
import simbot_codegen.composeapp.generated.resources.Res
1816
import org.w3c.dom.get
1917
import org.w3c.dom.set
20-
import web.console.console
18+
import simbot_codegen.composeapp.generated.resources.JetBrainsMono_Medium
19+
import simbot_codegen.composeapp.generated.resources.LXGWNeoXiHeiScreen
20+
import simbot_codegen.composeapp.generated.resources.Res
21+
22+
// External JavaScript function declarations
23+
external fun notifyFontLoadingStart()
24+
external fun notifyFontLoadingComplete()
2125

2226
private const val THEME_PREFERENCE_KEY = "simbot_codegen_theme_preference"
2327

@@ -54,12 +58,25 @@ fun App() {
5458
val lxgwNeo by preloadFont(resource = Res.font.LXGWNeoXiHeiScreen)
5559
val fm = lxgwNeo?.let { FontFamily(it) }
5660

61+
// 通知字体加载状态
62+
LaunchedEffect(Unit) {
63+
// 应用启动时通知开始加载字体
64+
notifyFontLoadingStart()
65+
}
66+
67+
LaunchedEffect(fm) {
68+
if (fm != null) {
69+
// 字体加载完成时通知
70+
notifyFontLoadingComplete()
71+
}
72+
}
73+
5774
// 创建主题状态管理,从本地存储加载保存的主题偏好
5875
var colorMode by remember { mutableStateOf(loadThemePreference()) }
5976
val appContext = remember(colorMode) {
6077
AppContext(
6178
colorMode = colorMode,
62-
toggleColorMode = {
79+
toggleColorMode = {
6380
val newColorMode = colorMode.toggle()
6481
colorMode = newColorMode
6582
saveThemePreference(newColorMode)
@@ -70,45 +87,30 @@ fun App() {
7087
// 使用带动画过渡的颜色方案
7188
val colorScheme = rememberAnimatedColorScheme(colorMode)
7289

73-
AnimatedContent(fm) { fm ->
74-
if (fm == null) {
75-
Box(modifier = Modifier.fillMaxSize()) {
76-
Column(
77-
modifier = Modifier.align(Alignment.Center),
78-
verticalArrangement = Arrangement.Center,
79-
horizontalAlignment = Alignment.CenterHorizontally,
80-
) {
81-
CircularProgressIndicator(modifier = Modifier.align(Alignment.CenterHorizontally))
82-
Spacer(Modifier.padding(8.dp))
83-
Text("Font loading...")
84-
}
85-
}
86-
} else {
87-
CompositionLocalProvider(LocalAppContext provides appContext) {
88-
MaterialTheme(
89-
colorScheme = colorScheme,
90-
typography = MaterialTheme.typography.copy(
91-
displayLarge = MaterialTheme.typography.displayLarge.copy(fontFamily = fm),
92-
displayMedium = MaterialTheme.typography.displayMedium.copy(fontFamily = fm),
93-
displaySmall = MaterialTheme.typography.displaySmall.copy(fontFamily = fm),
94-
headlineLarge = MaterialTheme.typography.headlineLarge.copy(fontFamily = fm),
95-
headlineMedium = MaterialTheme.typography.headlineMedium.copy(fontFamily = fm),
96-
headlineSmall = MaterialTheme.typography.headlineSmall.copy(fontFamily = fm),
97-
titleLarge = MaterialTheme.typography.titleLarge.copy(fontFamily = fm),
98-
titleMedium = MaterialTheme.typography.titleMedium.copy(fontFamily = fm),
99-
titleSmall = MaterialTheme.typography.titleSmall.copy(fontFamily = fm),
100-
bodyLarge = MaterialTheme.typography.bodyLarge.copy(fontFamily = fm),
101-
bodyMedium = MaterialTheme.typography.bodyMedium.copy(fontFamily = fm),
102-
bodySmall = MaterialTheme.typography.bodySmall.copy(fontFamily = fm),
103-
labelLarge = MaterialTheme.typography.labelLarge.copy(fontFamily = fm),
104-
labelMedium = MaterialTheme.typography.labelMedium.copy(fontFamily = fm),
105-
labelSmall = MaterialTheme.typography.labelSmall.copy(fontFamily = fm),
106-
)
107-
) {
108-
GradleSettingsView()
109-
}
90+
AnimatedVisibility(fm != null) {
91+
CompositionLocalProvider(LocalAppContext provides appContext) {
92+
MaterialTheme(
93+
colorScheme = colorScheme,
94+
typography = MaterialTheme.typography.copy(
95+
displayLarge = MaterialTheme.typography.displayLarge.copy(fontFamily = fm),
96+
displayMedium = MaterialTheme.typography.displayMedium.copy(fontFamily = fm),
97+
displaySmall = MaterialTheme.typography.displaySmall.copy(fontFamily = fm),
98+
headlineLarge = MaterialTheme.typography.headlineLarge.copy(fontFamily = fm),
99+
headlineMedium = MaterialTheme.typography.headlineMedium.copy(fontFamily = fm),
100+
headlineSmall = MaterialTheme.typography.headlineSmall.copy(fontFamily = fm),
101+
titleLarge = MaterialTheme.typography.titleLarge.copy(fontFamily = fm),
102+
titleMedium = MaterialTheme.typography.titleMedium.copy(fontFamily = fm),
103+
titleSmall = MaterialTheme.typography.titleSmall.copy(fontFamily = fm),
104+
bodyLarge = MaterialTheme.typography.bodyLarge.copy(fontFamily = fm),
105+
bodyMedium = MaterialTheme.typography.bodyMedium.copy(fontFamily = fm),
106+
bodySmall = MaterialTheme.typography.bodySmall.copy(fontFamily = fm),
107+
labelLarge = MaterialTheme.typography.labelLarge.copy(fontFamily = fm),
108+
labelMedium = MaterialTheme.typography.labelMedium.copy(fontFamily = fm),
109+
labelSmall = MaterialTheme.typography.labelSmall.copy(fontFamily = fm),
110+
)
111+
) {
112+
GradleSettingsView()
110113
}
111114
}
112115
}
113-
114116
}

composeApp/src/wasmJsMain/kotlin/love/forte/simbot/codegen/main.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import kotlinx.dom.clear
77

88
@OptIn(ExperimentalComposeUiApi::class)
99
fun main() {
10-
document.getElementById("codegen-root-load-script")?.remove()
11-
document.getElementById("codegen-root")?.clear()
12-
13-
val root = document.body!!
10+
// 不立即移除加载脚本和清空加载动画
11+
// 让字体加载过程来控制这些元素的移除
12+
13+
val root = document.getElementById("codegen-root")!!
1414

1515
ComposeViewport(root) {
1616
App()

composeApp/src/wasmJsMain/resources/index.html

Lines changed: 99 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -368,62 +368,74 @@
368368
border-radius: 50%;
369369
margin-right: 5px;
370370
}
371+
372+
/* 确保 codegen-root 容器占满全屏,不受加载动画影响 */
373+
#codegen-root {
374+
width: 100vw;
375+
height: 100vh;
376+
position: fixed;
377+
top: 0;
378+
left: 0;
379+
overflow: hidden;
380+
}
371381
</style>
372382
</head>
373383
<body>
374-
<div id="codegen-root">
375-
<div class="loading-container" id="loading-container">
376-
<!-- 浮动粒子背景 -->
377-
<div class="floating-particles" id="floating-particles"></div>
378-
379-
<!-- 加载器 -->
380-
<div class="loader">
381-
<!-- 波纹效果 -->
382-
<div class="ripple"></div>
383-
<div class="ripple"></div>
384-
<div class="ripple"></div>
385-
386-
<!-- 轨道与粒子 -->
387-
<div class="orbit">
388-
<div class="orbit-particle"></div>
389-
</div>
390-
<div class="orbit">
391-
<div class="orbit-particle"></div>
392-
</div>
393-
<div class="orbit">
394-
<div class="orbit-particle"></div>
395-
</div>
396-
397-
<!-- 中心脉冲和核心 -->
398-
<div class="pulse"></div>
399-
<div class="core"></div>
384+
<!-- Loading animation as overlay - independent of codegen-root -->
385+
<div class="loading-container" id="loading-container">
386+
<!-- 浮动粒子背景 -->
387+
<div class="floating-particles" id="floating-particles"></div>
388+
389+
<!-- 加载器 -->
390+
<div class="loader">
391+
<!-- 波纹效果 -->
392+
<div class="ripple"></div>
393+
<div class="ripple"></div>
394+
<div class="ripple"></div>
395+
396+
<!-- 轨道与粒子 -->
397+
<div class="orbit">
398+
<div class="orbit-particle"></div>
400399
</div>
401-
402-
<!-- 进度条 -->
403-
<div class="progress-container">
404-
<div class="progress-bar" id="progress-bar"></div>
400+
<div class="orbit">
401+
<div class="orbit-particle"></div>
405402
</div>
406-
<div class="progress-text" id="progress-text">正在加载...</div>
407-
408-
<!-- 代码动画 -->
409-
<div class="code-animation">
410-
<div class="code-line" id="code-line">正在初始化 Simbot Codegen ...</div>
403+
<div class="orbit">
404+
<div class="orbit-particle"></div>
411405
</div>
412406

413-
<!-- 信息标签 -->
414-
<div class="tags">
415-
<div class="tag">初始化环境</div>
416-
<div class="tag">加载资源</div>
417-
<div class="tag">准备渲染</div>
418-
</div>
407+
<!-- 中心脉冲和核心 -->
408+
<div class="pulse"></div>
409+
<div class="core"></div>
410+
</div>
419411

420-
<!-- 信息文本 -->
421-
<div class="info-text">
422-
Simbot Codegen 正在准备中
423-
</div>
412+
<!-- 进度条 -->
413+
<div class="progress-container">
414+
<div class="progress-bar" id="progress-bar"></div>
415+
</div>
416+
<div class="progress-text" id="progress-text">正在加载...</div>
417+
418+
<!-- 代码动画 -->
419+
<div class="code-animation">
420+
<div class="code-line" id="code-line">正在初始化 Simbot Codegen ...</div>
421+
</div>
422+
423+
<!-- 信息标签 -->
424+
<div class="tags">
425+
<div class="tag">初始化环境</div>
426+
<div class="tag">加载资源</div>
427+
<div class="tag">准备渲染</div>
428+
</div>
429+
430+
<!-- 信息文本 -->
431+
<div class="info-text">
432+
Simbot Codegen 正在准备中
424433
</div>
425434
</div>
426435

436+
<!-- Compose app container - now empty and ready for Compose content -->
437+
<div id="codegen-root"></div>
438+
427439
<script id="codegen-root-load-script">
428440
// 创建浮动粒子
429441
function createFloatingParticles() {
@@ -498,18 +510,15 @@
498510
script.src = 'composeApp.js';
499511
script.type = 'application/javascript';
500512

501-
// 脚本加载完成后隐藏加载界面
513+
// 脚本加载完成后更新为字体加载状态
502514
script.onload = () => {
503515
// 确保进度条达到100%
504516
progressBar.style.width = '100%';
505-
progressText.textContent = '加载完成 (100%)';
506-
507-
// 短暂延迟后隐藏加载界面
508-
setTimeout(() => {
509-
loadingContainer.style.display = 'none';
510-
}, 800);
517+
progressText.textContent = '应用加载完成 (100%)';
511518

512519
clearInterval(interval);
520+
521+
// 不立即隐藏,等待字体加载完成的通知
513522
};
514523

515524
// 脚本加载出错
@@ -521,6 +530,44 @@
521530
// 添加脚本到文档
522531
document.head.appendChild(script);
523532
});
533+
534+
// 全局函数:通知开始加载字体
535+
window.notifyFontLoadingStart = function() {
536+
console.log("notifyFontLoadingStart")
537+
const progressText = document.getElementById('progress-text');
538+
const codeLine = document.getElementById('code-line');
539+
540+
if (progressText) {
541+
progressText.textContent = '加载字体中...';
542+
}
543+
if (codeLine) {
544+
codeLine.textContent = '正在加载字体文件...';
545+
}
546+
};
547+
548+
// 全局函数:通知字体加载完成,隐藏加载动画
549+
window.notifyFontLoadingComplete = function() {
550+
console.log("notifyFontLoadingComplete")
551+
const loadingContainer = document.getElementById('loading-container');
552+
const progressText = document.getElementById('progress-text');
553+
554+
if (progressText) {
555+
progressText.textContent = '字体加载完成!';
556+
}
557+
558+
// 短暂延迟后隐藏加载界面
559+
setTimeout(() => {
560+
if (loadingContainer) {
561+
loadingContainer.style.transition = 'opacity 0.5s ease-out';
562+
loadingContainer.style.opacity = '0';
563+
564+
setTimeout(() => {
565+
loadingContainer.style.display = 'none';
566+
loadingContainer.remove()
567+
}, 500);
568+
}
569+
}, 300);
570+
};
524571
</script>
525572
</body>
526573
</html>

0 commit comments

Comments
 (0)