Cinematic Web — 有意图的运动
用于构建电影感网页体验的技能:网站看起来像电影,滚动是镜头,每个元素都带着时间、份量和优雅进入。基础技术栈是 Next.js + Tailwind + GSAP + ScrollTrigger + Lenis,但核心(运动系统)也可移植到纯 HTML/CSS、WordPress/Divi 和 LearnWorlds。
核心哲学: 电影感网站不是快——而是慢得有意图。 匆忙是优雅的敌人。在任何一行代码之前,运动就被决定了;代码只是服从。
黄金法则(永不打破的定律)
三个库,三个职责。混淆它们是移动端滚动抖动和 Bug 的头号原因:
| 库 | 唯一职责 | 绝不做什么 |
|---|---|---|
| Lenis | 平滑滚动(惯性、滚动“份量”) | 不带动画元素 |
| GSAP | 元素的运动(位置、不透明度、缩放) | 不控制页面滚动 |
| ScrollTrigger | 编排——每个动画在滚动时何时/如何触发 | 不运行自己的滚动循环 |
区分业余与专业的关键细节:Lenis 和 ScrollTrigger 必须共享同一个时间循环(gsap.ticker)。 如果它们在各自的 RAF 中运行,scrub 就会抖动(jitter)。规范集成在 assets/lib/lenis-provider.tsx 中——始终使用这个模式,绝不放两个独立的 requestAnimationFrame。
// 集成的核心(完整细节见 references/01-setup.md):
lenis.on('scroll', ScrollTrigger.update); // Lenis 每次滚动通知 ScrollTrigger
gsap.ticker.add((time) => lenis.raf(time * 1000)); // GSAP 驱动 Lenis 的 RAF(单一时间源)
gsap.ticker.lagSmoothing(0);
运动系统(令牌,而非即兴)
“艺术打磨”不是在最后靠肉眼审查——它从一开始就由 assets/lib/motion.ts 中的集中令牌强制。每个动画都从这里取值。这使得打磨是确定性的。
标准持续时间(秒):
| 令牌 | 值 | 用途 |
|---|---|---|
fast | 0.6 | 绝对最小值。没有任何电影感的东西低于 0.6 秒。 |
base | 0.9 | 文本和图像的默认 reveal |
slow | 1.2 | 英雄区、章节入口、呼吸时刻 |
epic | 1.8 | 锚点过渡、“镜头时刻” |
标准缓动(运动的“签名”):
| 令牌 | 值 | 感觉 |
|---|---|---|
out | power3.out | 默认值。 果断进入,优雅减速 |
inOut | power3.inOut | 来回运动(pin、镜头) |
expo | expo.out | 戏剧性 reveal,高速对比 |
soft | power2.out | 微妙的微交互 |
打磨规则(第五阶段): 任何低于
0.6s的过渡都会被延长。任何不是power或expo的ease(例如linear、back、bounce、elastic)都会被替换——它们会破坏电影感的沉稳。元素序列之间stagger:0.15–0.2 秒。
工作流——5 个阶段
按顺序执行。每个阶段都有一个包含完整、即插即用配方的参考文件。在生成该阶段的代码之前,请阅读该阶段的参考文件。
阶段 1 —— 项目圣经(永远不要让 AI 猜测)
在任何组件之前,确立规则。使用 assets/CLAUDE.md 中的模板创建/更新项目根目录下的 CLAUDE.md,并按照 references/01-setup.md 进行技术栈设置。
- 安装:
gsap @gsap/react lenis(如果是新项目,再加 Next/Tailwind)。 - 在
CLAUDE.md中固定黄金法则和运动系统。 - 将
assets/lib/lenis-provider.tsx和assets/lib/motion.ts复制到项目中。 - 还不要生成组件。 先打地基。
阶段 2 —— 电影英雄区
第一印象定调:第一次交互之前的张力和流畅感。完整配方见 references/02-hero.md。
- 全屏,循环视频作为背景(带有图片备用和叠加层)。
- 文本以平滑 reveal 出现(mask +
y/opacity,slow+expo.out),并使用stagger按顺序出现。 - 滚动指示器在用户开始向下滚动时消失。
阶段 3 —— “镜头感”滚动
魔法发生的地方:滚动变成摄像机运动。配方(pin、序列、视差、scrub)见 references/03-scroll-camera.md。
- 通过 ScrollTrigger 实现固定滚动的章节。
- 元素按序列进入(
stagger0.15–0.2 秒),缓动为power3.out。 - 受控滚动(
scrub),而非自由动画——时间跟随用户的手指。
阶段 4 —— 驯服移动端的混乱
复杂的动画在移动端崩溃是设计问题,而非偶然。策略见 references/04-mobile-a11y.md。
- 使用
gsap.matchMedia()分离桌面端与移动端——而非在代码中散布if。 - 尊重
prefers-reduced-motion(可访问性 + 防晕动 + 法律风险)。 - 性能:仅动画
transform/opacity,避免在触摸设备上使用沉重的pin,检查 Lenis↔ScrollTrigger 冲突。 - 在修正移动端时,不要改变桌面的美学。
阶段 5 —— 艺术打磨
将“动画”与“电影感”区分开来的最后抛光。清单见 references/05-refinamento.md。
- 所有
< 0.6s的过渡 → 延长。 - 所有非
power/expo的ease→ 替换。 - 检查一致性:一切是否都来自
motion.ts?时间呼吸是否同步?
质量检查清单(交付前运行)
- Lenis 和 ScrollTrigger 共享
gsap.ticker(无双重 RAF)。 - 使用
useGSAP(来自@gsap/react)配合scope的 React 动画 → 自动清理,无路由间泄漏。 - 包含 GSAP 的组件均为
"use client"并注册插件(gsap.registerPlugin(ScrollTrigger, useGSAP))。 - 所有时间/缓动来自
motion.ts—— 代码中零魔法数字。 -
gsap.matchMedia()覆盖桌面和移动端;prefers-reduced-motion关闭或缩短运动。 - 仅动画
transform和opacity(不动画width、top、margin→ 回流)。 - 在加载会改变页面高度的字体/图像后调用
ScrollTrigger.refresh()。 - 无低于 0.6 秒的动画;无
linear/back/bounce/elastic。
可移植性(在 Next.js 之外)
运动系统和黄金法则在任何环境中都适用。对于纯 HTML/CSS、WordPress/Divi 或 LearnWorlds:通过 CDN 使用 GSAP + ScrollTrigger + Lenis,保持相同的持续时间/缓动令牌,并使用前缀类和选择器以避免样式泄漏到平台中。具体说明见 references/01-setup.md 末尾。
技能文件地图
assets/CLAUDE.md—— 项目圣经模板(复制到根目录并调整)。assets/lib/lenis-provider.tsx—— 集成了 Lenis↔GSAP 规范集成的 React/Next Provider。assets/lib/motion.ts—— 运动令牌(持续时间、缓动、reveal 辅助函数)。references/01-setup.md—— 技术栈、安装、集成、SSR/Next、可移植性。references/02-hero.md—— 完整的电影英雄区配方。references/03-scroll-camera.md—— pin、stagger、视差、scrub、水平滚动。references/04-mobile-a11y.md—— matchMedia、reduced-motion、性能、移动端调试。references/05-refinamento.md—— 详细的运动系统和收尾清单。