优化加载动画

This commit is contained in:
2026-04-18 11:03:34 +08:00
parent 70d42e6792
commit 5cbb7217f0
9 changed files with 320 additions and 39 deletions
+38
View File
@@ -12,12 +12,30 @@
--copper-deep: #964722;
--olive: #76845e;
--olive-deep: #596946;
--font-body:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
"PingFang SC",
"Hiragino Sans GB",
"Microsoft YaHei UI",
"Microsoft YaHei",
sans-serif;
--font-display:
ui-serif,
"Songti SC",
"STSong",
"SimSun",
"Times New Roman",
serif;
}
@theme inline {
--color-background: var(--paper);
--color-foreground: var(--ink);
--font-sans: var(--font-body);
--font-serif: var(--font-display);
}
* {
@@ -52,6 +70,26 @@ select {
background: rgba(199, 103, 51, 0.18);
}
@keyframes route-progress-slide {
0% {
transform: translateX(-140%) scaleX(0.72);
}
55% {
transform: translateX(78%) scaleX(1);
}
100% {
transform: translateX(240%) scaleX(0.86);
}
}
.route-progress-bar {
animation: route-progress-slide 1.15s ease-in-out infinite;
transform-origin: left center;
box-shadow: 0 0 18px rgba(199, 103, 51, 0.28);
}
.paper-panel {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 249, 241, 0.84)),
+5 -14
View File
@@ -1,18 +1,7 @@
import type { Metadata, Viewport } from "next";
import { Noto_Sans_SC, Noto_Serif_SC } from "next/font/google";
import "./globals.css";
const bodyFont = Noto_Sans_SC({
variable: "--font-body",
subsets: ["latin"],
weight: ["400", "500", "700"],
});
const displayFont = Noto_Serif_SC({
variable: "--font-display",
subsets: ["latin"],
weight: ["400", "600", "700"],
});
import { NavigationProgressProvider } from "@/components/navigation-progress";
export const metadata: Metadata = {
metadataBase: new URL("https://digital-human.xn--876a.net"),
@@ -58,8 +47,10 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="zh-CN" className={`${bodyFont.variable} ${displayFont.variable}`}>
<body className="min-h-screen">{children}</body>
<html lang="zh-CN">
<body className="min-h-screen">
<NavigationProgressProvider>{children}</NavigationProgressProvider>
</body>
</html>
);
}
+31 -12
View File
@@ -1,40 +1,59 @@
import Link from "next/link";
import { PanelShell } from "@/components/panel-shell";
import { ScanClient } from "@/components/scan-client";
import { requireCaregiverSession } from "@/lib/page-auth";
import { getCaregiverDisplayName } from "@/lib/session";
export const dynamic = "force-dynamic";
export default async function ScanPage() {
const caregiver = await requireCaregiverSession("/scan");
export default function ScanPage() {
return (
<main className="mx-auto min-h-screen max-w-5xl px-4 py-8 sm:px-6 lg:px-8">
<section className="grid gap-6 lg:grid-cols-[0.82fr_1.18fr]">
<div className="rounded-[36px] border border-white/70 bg-white/78 p-6 shadow-[0_30px_70px_rgba(115,76,42,0.14)] backdrop-blur">
<PanelShell
currentPath="/scan"
title="扫码连接"
description="把镜头对准长辈手机上的二维码,识别后会自动完成连接并跳转到绑定结果。"
caregiverLabel={getCaregiverDisplayName(caregiver)}
>
<section className="grid gap-6 xl:grid-cols-[0.88fr_1.12fr]">
<article className="rounded-[32px] border border-white/75 bg-white/82 p-6 shadow-[0_26px_60px_rgba(115,76,42,0.12)]">
<p className="text-sm font-medium tracking-[0.18em] text-[var(--copper)] uppercase">
扫码连接
扫码步骤
</p>
<h1 className="mt-4 font-[family-name:var(--font-display)] text-4xl leading-[1.15] text-[var(--ink)]">
<h2 className="mt-2 font-[family-name:var(--font-display)] text-3xl text-[var(--ink)]">
对准长辈手机上的二维码
</h1>
</h2>
<p className="mt-4 text-base leading-8 text-[var(--muted)]">
扫描成功后,系统会自动将长辈的设备连接到您的账号。之后就能随时查看长辈的留言和使用动态。
扫描成功后,系统会自动把长辈的设备连接到当前账号。连接完成后,就能继续查看留言、动态和设备详情。
</p>
<div className="mt-6 space-y-3 rounded-[28px] bg-[var(--paper-soft)] p-5 text-sm leading-7 text-[var(--muted)]">
<div className="mt-4 space-y-3 rounded-[24px] bg-[var(--paper-soft)] p-5 text-sm leading-7 text-[var(--muted)]">
<p>1. 让长辈打开手机上的「家人连接」页面。</p>
<p>2. 将镜头对准屏幕上的二维码,保持一两秒即可。</p>
<p>3. 连接成功后会自动跳转。</p>
</div>
<div className="mt-5 rounded-[24px] bg-[var(--paper-soft)] px-5 py-4">
<p className="text-sm font-semibold text-[var(--ink)]">小提醒</p>
<p className="mt-2 text-sm leading-7 text-[var(--muted)]">
如果当前设备没有摄像头,或者浏览器没有拿到拍照权限,可以回到设备页,改用粘贴设备码的方式继续连接。
</p>
</div>
<div className="mt-6 flex flex-wrap gap-3">
<Link
href="/devices"
className="inline-flex h-12 items-center justify-center rounded-full border border-[var(--line)] bg-white px-5 text-sm font-semibold text-[var(--ink)] transition hover:bg-[var(--paper-soft)]"
className="inline-flex h-12 items-center justify-center rounded-full bg-[var(--olive)] px-5 text-sm font-semibold text-white transition hover:bg-[var(--olive-deep)]"
>
返回设备页
</Link>
</div>
</div>
</article>
<ScanClient />
</section>
</main>
</PanelShell>
);
}
+1 -1
View File
@@ -15,7 +15,7 @@ export default async function SettingsPage() {
<PanelShell
currentPath="/settings"
title="设置"
description="桌面版安装、消息提醒和推送测试统一放在这里,不再分散显示在各个页面。"
description="PWA 桌面版安装,安装后即可接收实时消息推送。"
caregiverLabel={getCaregiverDisplayName(caregiver)}
>
<section className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">