From d2650898750da239eb364640ff1be0dc19fc73c1 Mon Sep 17 00:00:00 2001
From: lyf <2514544224@qq.com>
Date: Mon, 13 Jul 2026 17:37:41 +0800
Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E9=A6=96=E9=A1=B5=E5=8A=A0?=
=?UTF-8?q?=E8=BD=BD=E9=A1=B5=E5=B9=B6=E8=A1=A5=E5=85=85=E5=93=81=E7=89=8C?=
=?UTF-8?q?=E6=A0=87=E8=AF=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
design-qa.md | 40 ++++
src/pages/index/index.vue | 300 ++++++--------------------
static/guide/museum-brand-icons.webp | Bin 0 -> 12374 bytes
tests/unit/IndexLaunchOverlay.spec.ts | 26 +++
4 files changed, 132 insertions(+), 234 deletions(-)
create mode 100644 design-qa.md
create mode 100644 static/guide/museum-brand-icons.webp
create mode 100644 tests/unit/IndexLaunchOverlay.spec.ts
diff --git a/design-qa.md b/design-qa.md
new file mode 100644
index 0000000..ec1fdab
--- /dev/null
+++ b/design-qa.md
@@ -0,0 +1,40 @@
+# 加载页设计 QA
+
+- source visual truth path: `C:\Users\ADMINI~1\AppData\Local\Temp\codex-clipboard-6d038678-2d48-4ee0-b4fc-152d414e7184.png`
+- implementation screenshot path: `C:\Users\Administrator\AppData\Local\Temp\museum-launch-390x844.png`
+- comparison evidence path: `C:\Users\Administrator\AppData\Local\Temp\museum-launch-comparison.png`
+- viewport: `360x800`、`390x844`、`430x932`
+- state: 首页首次进入,加载层可见,加载进度进行中
+
+## Full-view Comparison Evidence
+
+白色全屏背景中仅保留彩色 Logo、英文馆名、中文馆名和原生进度动效。实现层级、内容顺序和居中关系与参考图一致,没有继续使用全屏背景图、蒙层、口号、状态卡或加载说明文案。
+
+## Focused Region Comparison Evidence
+
+对 Logo 与馆名区域进行了聚焦对比。Logo 使用参考图中的真实彩色图形资产,馆名使用页面文字以减少图片体积。360px、390px、430px 三档视口中 Logo 均完整加载,中英文馆名均未换行或溢出,进度动效可见。
+
+## Fidelity Surfaces
+
+- Fonts and typography: 英文使用无衬线字体栈并保持单行;中文使用宋体字体栈,字重和留白接近参考图。
+- Spacing and layout rhythm: Logo、英文、中文和进度条垂直居中排列,三档移动视口无裁切或重叠。
+- Colors and visual tokens: 白色背景、黑色馆名和博物馆黄绿色加载色符合现有品牌色。
+- Image quality and asset fidelity: Logo 来自参考图真实图形区域,WebP 尺寸为 `738x106`,约 12 KB;未使用 CSS 绘图、SVG 或占位图替代。
+- Copy and content: 英文馆名为 `SHENZHEN NATURAL HISTORY MUSEUM`,中文馆名为 `深圳自然博物馆`。
+
+## Findings
+
+无 P0、P1 或 P2 问题。
+
+## Patches Made
+
+- 移除旧的两张全屏加载图、蒙层、口号、状态卡、加载说明和恢复按钮。
+- 增加彩色 Logo 图形资产,馆名改为页面文字。
+- 保留现有加载进度、最短展示时间、模型完成、超时和淡出逻辑。
+- 修复本地验证环境中的旧 Vite 进程,确认新静态资源可正常加载。
+
+## Follow-up Polish
+
+无阻塞项。
+
+final result: passed
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 3e18a2e..7535acc 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -263,38 +263,24 @@
:class="{ leaving: launchOverlayLeaving }"
>
-
-
-
-
- 探索万物生息
- 深圳自然博物馆
- Shenzhen Natural History Museum
-
-
- {{ launchLoadingText }}
-
-
-
-
-
- 重新加载
-
-
- 继续进入
-
-
+
+
+ SHENZHEN NATURAL HISTORY MUSEUM
+ 深圳自然博物馆
+
@@ -381,7 +367,6 @@ const topTabFromHash = () => {
const launchOverlayMinDisplayMs = 700
const launchOverlayGuideTimeoutMs = 12000
const launchOverlayNonGuideTimeoutMs = 900
-const launchOverlayDefaultText = '正在进入智能导览'
const shouldShowLaunchOverlay = () => {
if (typeof window === 'undefined') return false
@@ -407,11 +392,7 @@ const currentTab = ref(initialTopTab())
const launchOverlayVisible = ref(shouldShowLaunchOverlay())
const launchOverlayLeaving = ref(false)
const launchProgress = ref(8)
-const launchLoadingText = ref(launchOverlayDefaultText)
const launchInitialModelSettled = ref(false)
-const launchOverlayRecoverable = ref(false)
-const launchImageLoaded = ref(false)
-const launchImageFailed = ref(false)
const showRoutePlanner = ref(false)
const routeStartPoint = ref(null)
const routeEndPoint = ref(null)
@@ -448,10 +429,6 @@ let launchOverlayFadeTimer: ReturnType | null = null
let launchOverlayHideDelayTimer: ReturnType | null = null
let launchOverlayStartedAt = 0
-const launchProgressStyle = computed(() => ({
- width: `${launchProgress.value}%`
-}))
-
const clearLaunchTimers = () => {
if (launchOverlayFallbackTimer) {
clearTimeout(launchOverlayFallbackTimer)
@@ -515,8 +492,6 @@ const continueLaunchWithoutInitialModel = (reason: string, event?: { view: Guide
})
launchInitialModelSettled.value = true
- launchOverlayRecoverable.value = false
- launchLoadingText.value = launchOverlayDefaultText
launchProgress.value = Math.max(launchProgress.value, 96)
is3DMode.value = false
guideOutdoorState.value = 'home'
@@ -531,10 +506,8 @@ const startLaunchOverlay = () => {
clearLaunchTimers()
launchInitialModelSettled.value = false
- launchOverlayRecoverable.value = false
launchOverlayStartedAt = Date.now()
launchProgress.value = shouldWaitForLaunchModel() ? 8 : 68
- launchLoadingText.value = launchOverlayDefaultText
const timeoutMs = shouldWaitForLaunchModel()
? launchOverlayGuideTimeoutMs
@@ -552,52 +525,23 @@ const startLaunchOverlay = () => {
const handleInitialModelProgress = (event: { progress: number; message: string; view: GuideIndoorView; floorId?: string; elapsedMs?: number }) => {
if (!launchOverlayVisible.value || launchInitialModelSettled.value || !shouldWaitForLaunchModel()) return
- launchOverlayRecoverable.value = false
launchProgress.value = Math.min(99, Math.max(8, event.progress))
- launchLoadingText.value = launchOverlayDefaultText
}
const settleLaunchOverlayByModel = (status: 'ready' | 'failed', event?: { view: GuideIndoorView; floorId?: string; message?: string; elapsedMs?: number }) => {
launchInitialModelSettled.value = true
- launchOverlayRecoverable.value = status === 'failed'
if (status === 'failed') {
continueLaunchWithoutInitialModel('failed', event)
return
} else {
launchProgress.value = 100
- launchLoadingText.value = launchOverlayDefaultText
console.log('首页前置加载页收到初始模型加载完成:', event)
}
hideLaunchOverlay()
}
-const handleLaunchRetry = () => {
- if (typeof window !== 'undefined') {
- window.location.reload()
- }
-}
-
-const handleLaunchImageLoad = () => {
- launchImageLoaded.value = true
- launchImageFailed.value = false
-}
-
-const handleLaunchImageError = () => {
- launchImageLoaded.value = false
- launchImageFailed.value = true
-}
-
-const handleLaunchContinue = () => {
- launchOverlayRecoverable.value = false
- if (shouldWaitForLaunchModel() && !launchInitialModelSettled.value) {
- continueLaunchWithoutInitialModel('manual')
- return
- }
- hideLaunchOverlay()
-}
-
const showArrivalPanel = ref(false)
const showArrivalPanelCollapsed = ref(false)
const arrivalPanelRef = ref | null>(null)
@@ -1582,7 +1526,7 @@ const handleExplainBack = () => {
display: flex;
justify-content: center;
overflow: hidden;
- background: #e9e8dc;
+ background: #ffffff;
opacity: 1;
transition: opacity 0.36s ease, transform 0.36s ease;
}
@@ -1594,194 +1538,82 @@ const handleExplainBack = () => {
}
.app-launch-stage {
- position: relative;
width: 100%;
max-width: 430px;
height: 100vh;
height: 100dvh;
- min-height: 560px;
- overflow: hidden;
- background:
- radial-gradient(circle at 50% 20%, rgba(224, 225, 0, 0.24), rgba(224, 225, 0, 0) 34%),
- linear-gradient(180deg, #f5f5ed 0%, #e1e5d9 42%, #151713 100%);
- box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04);
-}
-
-.app-launch-image {
- position: absolute;
- inset: 0;
- z-index: 0;
- width: 100%;
- height: 100%;
- transform-origin: center;
-}
-
-.app-launch-image-lqip {
- filter: blur(10px);
- transform: scale(1.08);
-}
-
-.app-launch-image-full {
- opacity: 0;
- transform: scale(1.01);
- transition: opacity 0.24s ease;
-}
-
-.app-launch-image-full.loaded {
- opacity: 1;
-}
-
-.app-launch-shade {
- position: absolute;
- inset: 0;
- z-index: 1;
- background:
- linear-gradient(180deg, rgba(245, 245, 237, 0.92) 0%, rgba(245, 245, 237, 0.62) 24%, rgba(10, 12, 9, 0.08) 52%, rgba(0, 0, 0, 0.56) 100%),
- linear-gradient(180deg, rgba(224, 225, 0, 0.28) 0, rgba(224, 225, 0, 0) 138px);
-}
-
-.app-launch-brand {
- position: absolute;
- z-index: 2;
- top: calc(env(safe-area-inset-top) + 58px);
- left: 24px;
- right: 24px;
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.app-launch-kicker {
- width: fit-content;
- padding: 4px 8px;
- box-sizing: border-box;
- background: #000000;
- font-size: 12px;
- line-height: 17px;
- font-weight: 700;
- color: var(--museum-accent);
-}
-
-.app-launch-title {
- font-size: 31px;
- line-height: 39px;
- font-weight: 800;
- letter-spacing: 0;
- color: #000000;
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.46);
-}
-
-.app-launch-subtitle {
- max-width: 300px;
- font-size: 14px;
- line-height: 19px;
- font-weight: 500;
- color: #424754;
-}
-
-.app-launch-status {
- position: absolute;
- z-index: 2;
- left: 24px;
- right: 24px;
- bottom: calc(env(safe-area-inset-bottom) + 56px);
- padding: 16px;
- box-sizing: border-box;
- background: rgba(0, 0, 0, 0.88);
- border: 1px solid rgba(224, 225, 0, 0.34);
-}
-
-.app-launch-loading-text {
- display: block;
- font-size: 15px;
- line-height: 21px;
- font-weight: 700;
- color: #ffffff;
-}
-
-.app-launch-progress {
- height: 4px;
- margin-top: 12px;
- overflow: hidden;
- background: rgba(255, 255, 255, 0.18);
-}
-
-.app-launch-progress-bar {
- height: 100%;
- width: 18%;
- background: var(--museum-accent);
- transition: width 0.22s ease;
-}
-
-.app-launch-actions {
- margin-top: 14px;
- display: flex;
- gap: 10px;
-}
-
-.app-launch-action {
- height: 36px;
- flex: 1;
+ min-height: 480px;
display: flex;
align-items: center;
justify-content: center;
+ overflow: hidden;
+ background: #ffffff;
+}
+
+.app-launch-content {
+ width: 100%;
+ padding: 0 28px;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
box-sizing: border-box;
- border-radius: 8px;
+ transform: translateY(-3vh);
}
-.app-launch-action.secondary {
- background: rgba(255, 255, 255, 0.12);
- border: 1px solid rgba(255, 255, 255, 0.38);
+.app-launch-logo {
+ width: min(84vw, 350px);
+ height: auto;
}
-.app-launch-action.primary {
- background: var(--museum-accent);
- border: 1px solid var(--museum-accent);
-}
-
-.app-launch-action-text {
+.app-launch-name-en {
+ margin-top: 20px;
+ white-space: nowrap;
+ font-family: 'HarmonyOS Sans SC', 'HarmonyOS Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
font-size: 13px;
line-height: 18px;
- font-weight: 700;
- color: #ffffff;
+ font-weight: 500;
+ letter-spacing: 0;
+ color: #262421;
}
-.app-launch-action.primary .app-launch-action-text {
- color: #151713;
+.app-launch-name-cn {
+ margin-top: 8px;
+ white-space: nowrap;
+ font-family: 'Songti SC', STSong, SimSun, serif;
+ font-size: 36px;
+ line-height: 48px;
+ font-weight: 500;
+ letter-spacing: 0;
+ color: #000000;
+}
+
+.app-launch-progress {
+ width: 112px;
+ margin-top: 32px;
}
@media (max-width: 360px) {
- .app-launch-brand {
- top: calc(env(safe-area-inset-top) + 48px);
- left: 20px;
- right: 20px;
+ .app-launch-content {
+ padding: 0 24px;
}
- .app-launch-title {
- font-size: 28px;
- line-height: 36px;
+ .app-launch-logo {
+ width: calc(100vw - 52px);
}
- .app-launch-subtitle {
- font-size: 13px;
- line-height: 18px;
- }
-
- .app-launch-status {
- left: 20px;
- right: 20px;
- bottom: calc(env(safe-area-inset-bottom) + 42px);
- padding: 14px;
+ .app-launch-name-cn {
+ font-size: 32px;
+ line-height: 43px;
}
}
@media (max-height: 680px) {
- .app-launch-brand {
- top: calc(env(safe-area-inset-top) + 38px);
+ .app-launch-content {
+ transform: translateY(-1vh);
}
- .app-launch-status {
- bottom: calc(env(safe-area-inset-bottom) + 32px);
+ .app-launch-progress {
+ margin-top: 26px;
}
}
diff --git a/static/guide/museum-brand-icons.webp b/static/guide/museum-brand-icons.webp
new file mode 100644
index 0000000000000000000000000000000000000000..32250a4dadf77914161751c11dc25b774c7d1fc3
GIT binary patch
literal 12374
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
IARUaL09aFPVE_OC
literal 0
HcmV?d00001
diff --git a/tests/unit/IndexLaunchOverlay.spec.ts b/tests/unit/IndexLaunchOverlay.spec.ts
new file mode 100644
index 0000000..eb7ee84
--- /dev/null
+++ b/tests/unit/IndexLaunchOverlay.spec.ts
@@ -0,0 +1,26 @@
+import { readFileSync } from 'node:fs'
+import { fileURLToPath, URL } from 'node:url'
+import { describe, expect, it } from 'vitest'
+
+const indexPageSource = readFileSync(
+ fileURLToPath(new URL('../../src/pages/index/index.vue', import.meta.url)),
+ 'utf8'
+)
+
+const launchOverlaySource = indexPageSource.slice(
+ indexPageSource.indexOf('v-if="launchOverlayVisible"'),
+ indexPageSource.indexOf('')
+)
+
+describe('首页精简加载页', () => {
+ it('仅展示图形标识、文字馆名和原生加载动效', () => {
+ expect(launchOverlaySource).toContain('/static/guide/museum-brand-icons.webp')
+ expect(launchOverlaySource).toContain('SHENZHEN NATURAL HISTORY MUSEUM')
+ expect(launchOverlaySource).toContain('深圳自然博物馆')
+ expect(launchOverlaySource).toContain('