Files
Arkie-Library-Frontend/docs/superpowers/specs/2026-05-29-website-motion-ux-design.md
2026-05-29 10:44:54 +08:00

5.4 KiB
Raw Blame History

网站动画与 UX 提升 — 设计文件

日期: 2026-05-29 目标: 在不改变 UI 布局和颜色的前提下,为 Arkie Library 前端加入精致动画并提升使用者体验,效果与性能兼顾,并顺手清理冗余代码。


1. 背景与约束

  • 技术栈React 18 + TypeScript + Vite + Tailwind CSS。
  • 主题:深色 (#141319),金色重点 (#eeb726 / #ffd35c)。
  • 现有动画:ark-page-fade-in(页面淡入 240msark-header-menu-enter(菜单 clip-path 180ms皆已支援 prefers-reduced-motion
  • 硬约束
    • 不改变任何布局、颜色、字体、间距。仅加入「动作 / 时间 / 反馈」。
    • 全部动画必须尊重 prefers-reduced-motion: reduce
    • 效果与性能兼顾库需按需加载、bundle 影响最小化。

2. 决策(已与用户确认)

项目 决定
动画强度 适中活泼moderate & lively克制但明显
范围 全站(首页、浏览、分类、分类详情、搜索、关于、收藏)
实现方式 混合方案framer-motionLazyMotion 精简模式)+ 纯 CSS/Tailwind
冗余清理 实作中一并清理(如 RecommendedCard 内两边相同的三元运算)

库分工

  • framer-motion (v11, LazyMotion + m):页面切换退场动画(AnimatePresence)、弹簧悬停质感、筛选/排序卡片重排(layout)、复杂 stagger 编排。
  • CSS / Tailwind:骨架屏 shimmer、图片加载淡入、简单滚动出现无需 framer 的场景)。

3. 架构与组件

3.1 动画基础设施(一次建好,全站复用)

  • tailwind.config.js:新增 keyframesshimmerfade-in-upscale-in)、对应 animation,统一缓动 cubic-bezier(0.22, 1, 0.36, 1)
  • src/index.css:新增可复用工具类与 reduced-motion 保护。
  • src/motion/ 新目录:
    • MotionProvider.tsx:包 LazyMotiondomAnimation features全站只引入一次确保精简 bundle。
    • variants.ts:共享 variantsfadeInUpstaggerContainercardHoverpageTransition)与统一 transition 设定。
    • useRevealOnScroll.ts:轻量 IntersectionObserver hook元素进入视窗触发一次CSS 路径用)。
    • Reveal.tsx:薄包装组件,子元素滚动进入视窗时 fade-in-up内部用 framer 的 whileInView 或 CSS hook择一统一

3.2 页面切换退场framer-motion

  • PublicLayout<Outlet/> 外层用 AnimatePresence mode="wait",以 pathname+search 为 key。
  • 退场/进场使用 pageTransition variant淡入 + 轻微位移,~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/opacityGPU 友好),避免 layout thrash。
  • build 后检查 bundle 体积变化在可接受范围。

7. 实作顺序

  1. 安装 framer-motion + 建 src/motion/ 基础设施 + tailwind/CSS keyframes。
  2. MotionProvider 接入 app root。
  3. 页面切换退场PublicLayout
  4. Scroll reveal全站列表/区块)。
  5. 骨架屏 + 图片淡入。
  6. 悬停/微互动升级。
  7. Toast 反馈。
  8. 清理冗余代码。
  9. npm run build 验证 + reduced-motion 验证。

8. 验收标准

  • 视觉布局/颜色与改动前一致(仅多了动作)。
  • npm run build 通过bundle 增量可控framer 精简模式)。
  • 开启「减少动态效果」时网站仍可正常使用、无动画。
  • 全站列表有 scroll reveal、卡片有弹簧悬停、加载有骨架屏、下载有 toast。