Skip to content
7MrlanPublic

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

轻动 · Animation Studies

把细微的互动,收藏成卡片。项目包含从现有首页抽离的九个动画,以及新增的 DeepSeek「潜入答案」,放进可以暂停、重播和筛选的卡片中。查看效果时,也能直接打开对应源码。

只有动画,没有商品、价格、购买流程、登录或后台接口。

本地运行

需要 Node.js 22.18+(22 系列)或 24+,推荐 Node.js 24 LTS,与 .nvmrc 和 CI 一致。

git clone https://github.com/7Mrlan/animation.git
cd animation
npm ci
npm run dev

打开终端显示的本地地址,通常是 http://localhost:5173。

npm run typecheck  # TypeScript 严格检查
npm test           # 时间轴、几何、视口窗口与观察器注册表测试
npm run build      # 类型检查 + 生成 dist/
npm run preview    # 本地预览生产构建
npm run check      # 类型 + 测试 + 构建,与 CI 一致
npm run format     # 格式化代码和文档

为什么是这套框架

  • 沿用 React + TypeScript 和原动画组件的实现,减少重写带来的偏差,展示与运动逻辑分别维护。
  • 使用 Vite 构建静态演示,无需服务端渲染、路由或后端,产物可直接托管。
  • 样式采用 普通 CSS,可以直接阅读关键帧、变量和伪元素,不依赖样式框架。
  • 每个动画场景通过 React.lazy 单独分块,卡片进入预加载窗口时才请求 JS 与对应 CSS;Duo 再按需加载 Lottie light SVG,其余动画使用 CSS 或 requestAnimationFrame。
  • 运行时只有 React、React DOM 和 Lottie 三个依赖;字体使用系统字体,动画素材本地提供。

动画目录

卡片 内容 核心入口
01 层叠之间 卡片抽出、下沉、归位;悬停/聚焦/触摸展开 CardDeck.tsx · 时间轴
02 灵感引力场 Claude 标志、纸片、轨道、指针光晕 ClaudeField.tsx
03 星光慢行 Gemini 星形、双轨旋转、星点呼吸 Membership.tsx
04 代码微光 终端浮动、指针准星、背景网格视差 CodeWorkspace.tsx
05 一声 Hello Duo Lottie 循环与静态海报回退 DuoPlayer.tsx
06 讯息涟漪 手机浮动、消息交错出现、信号呼吸 TelegramSignal.tsx
07 光标来访 浮动窗口、光晕与装饰光标跟随 ProfileWindow.tsx
08 小小宇宙 轨道、悬浮粒子、中心呼吸 OrbitCore.tsx
09 一封轻盈的信 伪元素信封与反向浮动标签 FloatingMail.tsx

| 10 潜入答案 | 拖拽小鲸、流动水面、曲线巡游与鲸跃 | DeepSeekDive.tsx · 运动模型 |

每个组件旁边都有对应 CSS。Gemini 与 Duo 共用 Membership.css。查看文件面板还会显示动画所需的时间轴、播放器或 Hook,便于一起复制。

学习顺序

  1. 先看 FloatingMail / TelegramSignal,理解 @keyframes、伪元素和错峰延迟。
  2. 看 GeminiOrbit / OrbitCore,理解多组动画如何叠加,注意每组 transform 的作用层级。
  3. 看 ClaudeField / CodeWorkspace / ProfileWindow,理解指针坐标、CSS 变量和 RAF 合帧。
  4. 看 CardDeck 和 subscription-motion.ts,理解离散阶段、连续插值和层级交接。
  5. 看 DuoPlayer,理解异步加载、取消、失败回退和动画实例销毁。
  6. 看 DeepSeekDive,理解拖拽、水面冲击、曲线巡游和抛物线鲸跃。

完整的 动画学习手册 包含十个动画的逐章讲解,以及基础、播放控制、术语和 AI coding 四个专题。每个动画章节都有参数说明、动手练习和可复制的提示词。

原文件对应关系见 抽离记录,第三方图形出处见 素材说明。

结构

src/
  animations/       独立动画组件与对应 CSS(按场景分块加载)
  lib/              动画控制器、运动/水面计算、视口窗口与观察器注册表
  hooks/            可见性窗口、滚动显现与系统减少动态效果偏好
  components/       卡片外壳、源码对话框、图标
  catalog.tsx       十个动画的名称、说明、懒加载场景与源码路径
  App.tsx           筛选与全局播放状态
  styles.css        新的卡片画廊外观、滚动显现与窗口占位
public/brands/      原动画所需的本地素材和第三方许可

播放与可访问性

  • 只有视口附近(上下各 600px)的卡片会挂载动画场景,场景的 JS 和 CSS 也在这时才开始加载。离开 1000px 释放边界后卸载,卡片外壳始终保留,因此网格高度、锚点、查找和键盘顺序都不受影响。这是“动画场景的虚拟滚动”,不是把正文也虚拟化。
  • 预加载与释放使用不同的边界,避免停在边界时反复挂载;所有卡片同时只保留 4 个 IntersectionObserver(预加载、释放、显现、播放),页面可见性和减少动态效果也使用共享订阅。观察器的共享、多订阅和清理有独立单元测试。
  • React.lazy 的场景分块用 Suspense 占位;单个分块加载失败由卡片级错误边界兜底,不会让整页白屏。进入视口附近时开始加载,因此不会为了尚未出现的卡片下载全部动画代码。
  • 卡片滚动进入视口时淡入上移;桌面端下方区块淡入缩放,触屏使用更轻的透明度显现。显现只发生一次,向上滚回不会重新隐藏;键盘聚焦或指针进入会提前显现。显现观察整张卡片,播放观察内部舞台,文字可见但舞台在视口外时不会跑动画。
  • 预加载窗口内离屏、页面隐藏、打开源码面板时暂停,返回后继续;越过 1000px 释放边界后场景卸载,回到附近会重建并从初始状态开始。
  • 每张卡片和整页均可手动暂停,重播会重建该动画实例。
  • 遵循系统 prefers-reduced-motion,展示静态构图、Duo 海报,不开启循环动画和显现过渡;卡片展开、拖鲸等直接交互仍然可用。
  • 源码面板使用原生 <dialog>,支持 Esc、焦点约束及关闭后焦点返回。
  • 触屏设备使用更轻的绘制路径:关闭 backdrop-filter、持续的 drop-shadow/blur 和卡片的 scale 显现,改用不透明控件与 40px 触摸目标;指针场景在 pointerdown 就响应,触摸抬手不会把位置重置。
  • Duo 的 Lottie runtime 在首屏空闲预热;Lottie 实例在滚动停止 180ms 后才创建,触屏滚动期间暂停播放,避免 SVG 构建和播放落在滚动帧里。DeepSeek 的拖拽手柄保留 touch-action: none。
  • 手机可点击层叠卡片展开;所有卡片均提供触摸可用的播放工具。

静态部署

npm run build 后部署 dist/。base: './' 让产物支持根目录及 /animation/ 等子目录;Lottie 和海报路径也遵循同一规则。项目不需要环境变量。

线上演示:轻动 · Animation Studies。

仓库使用 .github/workflows/check.yml 自动检查和发布到 GitHub Pages。每次推送到 main,先安装依赖并运行 npm run check(类型检查、测试和构建),成功后上传 dist/ 并部署。PR 和其他分支只检查,不发布。也可在 GitHub Actions 的 Check and deploy Pages 页面手动运行工作流。

首次启用时,需要在仓库 Settings → Pages → Build and deployment 中选择 GitHub Actions;后续发布由工作流自动完成。本项目不需要配置部署密钥或环境变量。

来源说明

动画来自原项目当前工作区,只复制到新项目,原项目保持不动。保留原来的动画形状、配色、关键帧和主要时序,移除业务依赖,并重新设计展示卡片。信封示例根据原首页保留的 CSS 恢复最小 DOM。品牌图形与 Duo 动画保留其原有权利说明;详见 ATTRIBUTION。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages