From 38824a0055bfeef073f32f8308402e00696417e1 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 20 Aug 2026 09:45:49 +0800 Subject: [PATCH] fix: render metrics and smooth route transitions --- frontend/src/admin/AdminLayout.tsx | 7 ++- frontend/src/admin/pages/LiveBoard.tsx | 12 +++-- frontend/src/pageTransitions.css | 65 +++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/frontend/src/admin/AdminLayout.tsx b/frontend/src/admin/AdminLayout.tsx index d0cefe6..31c3ff3 100644 --- a/frontend/src/admin/AdminLayout.tsx +++ b/frontend/src/admin/AdminLayout.tsx @@ -35,6 +35,11 @@ export default function AdminLayout() { const [collapsed, setCollapsed] = useState(false) const navigate = useNavigate() const location = useLocation() + function navigateWithTransition(path: string) { + const startViewTransition = (document as unknown as { startViewTransition?: (callback: () => void) => void }).startViewTransition + if (startViewTransition) startViewTransition(() => navigate(path)) + else navigate(path) + } const outlet = useOutlet() const selectedKey = menuItems.find( @@ -66,7 +71,7 @@ export default function AdminLayout() { navigate(key)} + onClick={({ key }) => navigateWithTransition(String(key))} style={{ border: 'none', marginTop: 8 }} /> diff --git a/frontend/src/admin/pages/LiveBoard.tsx b/frontend/src/admin/pages/LiveBoard.tsx index 62d0c1c..d4175ef 100644 --- a/frontend/src/admin/pages/LiveBoard.tsx +++ b/frontend/src/admin/pages/LiveBoard.tsx @@ -62,12 +62,16 @@ export default function LiveBoard() { message.error('看板数据加载失败') } finally { try { - const [metrics, nodeResponse] = await Promise.all([getSystemMetrics(), api.get('/nodes')]) - setSystemMetrics(metrics) - setNodes(nodeResponse.data) + setSystemMetrics(await getSystemMetrics()) } catch { setSystemMetrics(null) } + try { + const nodeResponse = await api.get('/nodes') + setNodes(nodeResponse.data) + } catch { + setNodes([]) + } setLoading(false) } } @@ -176,4 +180,4 @@ export default function LiveBoard() { ) -} +} \ No newline at end of file diff --git a/frontend/src/pageTransitions.css b/frontend/src/pageTransitions.css index 6385155..aad2a30 100644 --- a/frontend/src/pageTransitions.css +++ b/frontend/src/pageTransitions.css @@ -1,28 +1,79 @@ .app-route-transition, .admin-page-transition { min-height: 100%; - animation: page-fade-slide-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both; - will-change: opacity, transform; + animation: page-soft-enter 260ms cubic-bezier(0.22, 1, 0.36, 1) both; + will-change: transform, opacity, filter; + background: transparent; } .admin-page-transition { transform-origin: top center; } -@keyframes page-fade-slide-in { +.route-loading { + min-height: 280px; + display: grid; + place-items: center; + border-radius: 24px; + background: linear-gradient(135deg, rgba(255,255,255,0.92), rgba(248,244,238,0.78)); +} + +.route-loading span { + width: 28px; + height: 28px; + border-radius: 999px; + border: 3px solid rgba(194, 105, 58, 0.2); + border-top-color: #C2693A; + animation: route-loading-spin 760ms linear infinite; +} + +::view-transition-old(root), +::view-transition-new(root) { + animation-duration: 220ms; + animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); +} + +::view-transition-old(root) { + animation-name: view-soft-out; +} + +::view-transition-new(root) { + animation-name: view-soft-in; +} + +@keyframes page-soft-enter { from { - opacity: 0; - transform: translateY(14px) scale(0.995); + opacity: 0.94; + transform: translate3d(18px, 0, 0) scale(0.998); + filter: blur(0.2px); } to { opacity: 1; - transform: translateY(0) scale(1); + transform: translate3d(0, 0, 0) scale(1); + filter: blur(0); } } +@keyframes view-soft-out { + from { opacity: 1; transform: translate3d(0, 0, 0); } + to { opacity: 0.96; transform: translate3d(-8px, 0, 0); } +} + +@keyframes view-soft-in { + from { opacity: 0.96; transform: translate3d(10px, 0, 0); } + to { opacity: 1; transform: translate3d(0, 0, 0); } +} + +@keyframes route-loading-spin { + to { transform: rotate(360deg); } +} + @media (prefers-reduced-motion: reduce) { .app-route-transition, - .admin-page-transition { + .admin-page-transition, + .route-loading span, + ::view-transition-old(root), + ::view-transition-new(root) { animation: none; } }