5.4 KiB
5.4 KiB
网站动画与 UX 提升 — 设计文件
日期: 2026-05-29 目标: 在不改变 UI 布局和颜色的前提下,为 Arkie Library 前端加入精致动画并提升使用者体验,效果与性能兼顾,并顺手清理冗余代码。
1. 背景与约束
- 技术栈:React 18 + TypeScript + Vite + Tailwind CSS。
- 主题:深色 (
#141319),金色重点 (#eeb726/#ffd35c)。 - 现有动画:
ark-page-fade-in(页面淡入 240ms)、ark-header-menu-enter(菜单 clip-path 180ms),皆已支援prefers-reduced-motion。 - 硬约束:
- 不改变任何布局、颜色、字体、间距。仅加入「动作 / 时间 / 反馈」。
- 全部动画必须尊重
prefers-reduced-motion: reduce。 - 效果与性能兼顾:库需按需加载、bundle 影响最小化。
2. 决策(已与用户确认)
| 项目 | 决定 |
|---|---|
| 动画强度 | 适中活泼(moderate & lively),克制但明显 |
| 范围 | 全站(首页、浏览、分类、分类详情、搜索、关于、收藏) |
| 实现方式 | 混合方案:framer-motion(LazyMotion 精简模式)+ 纯 CSS/Tailwind |
| 冗余清理 | 实作中一并清理(如 RecommendedCard 内两边相同的三元运算) |
库分工
- framer-motion (v11,
LazyMotion+m):页面切换退场动画(AnimatePresence)、弹簧悬停质感、筛选/排序卡片重排(layout)、复杂 stagger 编排。 - CSS / Tailwind:骨架屏 shimmer、图片加载淡入、简单滚动出现(无需 framer 的场景)。
3. 架构与组件
3.1 动画基础设施(一次建好,全站复用)
tailwind.config.js:新增keyframes(shimmer、fade-in-up、scale-in)、对应animation,统一缓动cubic-bezier(0.22, 1, 0.36, 1)。src/index.css:新增可复用工具类与 reduced-motion 保护。src/motion/新目录:MotionProvider.tsx:包LazyMotion(domAnimationfeatures),全站只引入一次,确保精简 bundle。variants.ts:共享 variants(fadeInUp、staggerContainer、cardHover、pageTransition)与统一 transition 设定。useRevealOnScroll.ts:轻量IntersectionObserverhook,元素进入视窗触发一次(CSS 路径用)。Reveal.tsx:薄包装组件,子元素滚动进入视窗时 fade-in-up(内部用 framer 的whileInView或 CSS hook,择一统一)。
3.2 页面切换退场(framer-motion)
- 在
PublicLayout的<Outlet/>外层用AnimatePresence mode="wait",以pathname+search为 key。 - 退场/进场使用
pageTransitionvariant(淡入 + 轻微位移,~220ms)。 - 取代现有
ark-page-fade-in(避免重复;保留 CSS 作为 reduced-motion fallback)。
3.3 滚动出现(Scroll Reveal)
- 列表/区块(首页 carousel/区段、浏览 grid、分类卡片)以
Reveal包装,依序 stagger(~60ms)淡入上浮,只触发一次。 - grid 大量项目时限制 stagger 上限,避免长列表整体延迟。
3.4 悬停与微互动(不改样式,仅加动作)
- 卡片:现有
hover:scale-[1.02]升级为 framer 弹簧整卡轻浮 + 阴影过渡(沿用金色边框)。 - 下载按钮:
active:scale点击反馈 + 完成时的状态过渡。 - 导航连结:金色下划线滑入(
gold-underline过渡化)。
3.5 载入与反馈(UX 重点)
- 骨架屏:新增
src/components/Skeleton.tsx(带 shimmer),用于列表/卡片/详情加载态,取代空白或突兀闪现。 - 图片淡入:图片
onLoad后淡入(卡片封面、详情图),避免硬切。 - Toast:轻量
src/components/Toast.tsx+ provider,下载成功/失败提示(沿用现有配色),无障碍aria-live。
4. 冗余代码清理
RecommendedCard.tsx:useFigmaDesign ? "group-hover:scale-[1.02]" : "group-hover:scale-[1.02]"→ 两边相同,简化。- spinner
useFigmaDesign ? "h-5 w-5 animate-spin" : "h-5 w-5 animate-spin"→ 简化。
- 实作各档案时移除遇到的同类重复(不做无关重构)。
5. 资料流 / 隔离
- 动画相关逻辑集中于
src/motion/,组件只引用 variants/hook,不内嵌魔术数字。 MotionProvider在 app root 包一次;各页面无需重复设定。- 骨架屏 / Toast 为独立、可单测的展示组件。
6. 无障碍与性能
- 所有 framer 动画与 CSS 动画在
prefers-reduced-motion: reduce下降级为无动作或纯淡入。 - 使用
LazyMotion精简 features,避免引入完整 framer bundle。 - 动画用
transform/opacity(GPU 友好),避免 layout thrash。 - build 后检查 bundle 体积变化在可接受范围。
7. 实作顺序
- 安装 framer-motion + 建
src/motion/基础设施 + tailwind/CSS keyframes。 MotionProvider接入 app root。- 页面切换退场(PublicLayout)。
- Scroll reveal(全站列表/区块)。
- 骨架屏 + 图片淡入。
- 悬停/微互动升级。
- Toast 反馈。
- 清理冗余代码。
npm run build验证 + reduced-motion 验证。
8. 验收标准
- 视觉布局/颜色与改动前一致(仅多了动作)。
npm run build通过,bundle 增量可控(framer 精简模式)。- 开启「减少动态效果」时网站仍可正常使用、无动画。
- 全站列表有 scroll reveal、卡片有弹簧悬停、加载有骨架屏、下载有 toast。