From 3cc7a4c01acb816bc5968ae2defd8b13874eaf63 Mon Sep 17 00:00:00 2001 From: AnNingUI Date: Fri, 15 Aug 2025 22:25:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E5=AF=B9=E9=9D=9Estar?= =?UTF-8?q?tViewTransition=E6=94=AF=E6=8C=81=E7=9A=84=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA=E5=9B=9E=E9=80=80?= =?UTF-8?q?=E7=9A=84=E4=B8=BB=E9=A2=98=E5=88=87=E6=8D=A2=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes: #583 --- frontend_nuxt/utils/theme.js | 54 +++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/frontend_nuxt/utils/theme.js b/frontend_nuxt/utils/theme.js index 8f6206436..93584aecd 100644 --- a/frontend_nuxt/utils/theme.js +++ b/frontend_nuxt/utils/theme.js @@ -24,11 +24,13 @@ function apply(mode) { : mode if (root.dataset.theme === newMode) return root.dataset.theme = newMode - + // 更新 meta 标签 const androidMeta = document.querySelector('meta[name="theme-color"]') const iosMeta = document.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]') - const themeColor = getComputedStyle(document.documentElement).getPropertyValue('--background-color').trim(); + const themeColor = getComputedStyle(document.documentElement) + .getPropertyValue('--background-color') + .trim() const themeStatus = newMode === 'dark' ? 'black-translucent' : 'default' if (androidMeta) { @@ -39,7 +41,7 @@ function apply(mode) { newAndroidMeta.content = themeColor document.head.appendChild(newAndroidMeta) } - + if (iosMeta) { iosMeta.content = themeStatus } else { @@ -106,10 +108,54 @@ function withViewTransition(event, applyFn, direction = true) { }) .catch(console.warn) } else { - applyFn() + fallbackThemeTransition(applyFn) } } +function fallbackThemeTransition(applyFn) { + if (!import.meta.client) return + + const root = document.documentElement + const computedStyle = getComputedStyle(root) + + // 获取当前背景色用于过渡 + const currentBg = computedStyle.getPropertyValue('--background-color').trim() + + // 创建过渡元素 + const transitionElement = document.createElement('div') + transitionElement.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: ${currentBg}; + z-index: 9999; + pointer-events: none; + backdrop-filter: blur(1px); + ` + document.body.appendChild(transitionElement) + + // 使用 Web Animations API 实现淡出动画 + const animation = transitionElement.animate([{ opacity: 1 }, { opacity: 0 }], { + duration: 300, + easing: 'ease-out', + }) + + // 应用主题变更 + applyFn() + + // 动画完成后清理 + animation.finished + .then(() => { + document.body.removeChild(transitionElement) + }) + .catch(() => { + // 降级处理 + document.body.removeChild(transitionElement) + }) +} + function getSystemTheme() { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' }