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('