跳到正文
返回博客
五个米白色运动状态沿路径展开,黑色证据门框住第三个状态。
作者
Zinian
发布时间
2026年8月5日
阅读时间
8 分钟阅读

前端

复刻网页动效时,截图几乎是最不够用的证据

Motion Replication Kit 把网页动效复刻从看图猜参数,改成一条带时间、推断边界、reduced-motion 和性能验收的证据链。

Motion Replication Kit 最早面对的问题,看起来很像一道找不同。

先截一张页面初始状态,再滚动一段距离,截第二张。两张图放在一起,标题上移了,卡片出现了,背景位置也变了。证据似乎已经齐了,接下来只要把 opacitytranslateY 和 duration 猜得像一点。

真正开始复刻以后才会发现,这两张图只证明了两个姿势。

它们没有告诉我中间发生了什么:元素是在 300ms 内结束,还是跟着滚动条走;先淡入再位移,还是两件事同时发生;五张卡片一起出现,还是按 80ms 错开;页面停在那个位置,是因为动画结束了,还是因为它被 pin 住了。

一个动效可以在起点和终点都对,动起来却完全不像。多少有点像只看两张剧照,认真复刻了一部电影。

所以我后来给这个工具定下的判断很简单:网页动效复刻首先是证据问题,之后才是 GSAP、CSS 或 Motion 的实现问题。

在第三帧里补回时间

早期 capture 流程保留 initial.pngscrolled.png。它很适合回答空间问题:滚动前后哪个元素可见,最终位置在哪里,页面有没有明显错位。

但项目自己的早期 PRD 也写得很直接:两个固定状态无法分析 scrub、pin 和多阶段滚动,截图本身也看不到 duration 与 easing。

于是 capture 后来没有寻找一张“更聪明的截图”,而是把证据拆开。

默认流程会沿滚动距离采五个时间点,保留 filmstrip;Playwright trace 记录页面在浏览器里发生过什么;需要时再录一段 video;initial.pngscrolled.png 继续留下,兼容旧流程,也方便快速比较前后状态。

这些文件不是同一种证据的重复备份。

截图负责空间,filmstrip 负责顺序,video 负责连续手感,trace 负责回到浏览器事件和时间线里排查。它们彼此有重叠,但没有谁能单独把动效讲完。

这也是我现在不太相信“给 Agent 一张参考图,它就能还原动效”这句话的原因。它或许能猜到一种合理的入场动画,但合理不等于原来的行为,更不等于已经被验证过。

每个推断都要带着回头路

有了多帧以后,下一步仍然不是直接生成代码。

工具会在每个采样点记录候选元素的位置、尺寸、透明度和 transform,也会读取 transition、animation、原生 scroll timeline,以及浏览器通过 Web Animations API 暴露的 duration、delay、easing 和 timeline 类型。随后,纯 Node 的推断层再根据位移、透明度差和进入步骤,给出 fade-upslide-inscale-in 或 stagger group 之类的候选解释。

这里最重要的设计不是“它能自动识别多少种动效”,而是所有写进 draft brief 的推断都带着同一句标记:(inferred — verify)

这句看起来有点啰嗦,但我宁愿它一直碍眼。

浏览器能提供真实 timing 时,那是观测值;根据五个采样点算出位移方向,是推断;看到类名里有 motion,只能算线索。把三者压成同一种“AI 已识别结果”,会让后面的 Agent 在一个猜测上继续精确施工。

我更愿意让系统在证据不足时留下空白,而不是补出一个很像答案的数字。duration 猜错 100ms 也许只是手感差一点;把 scroll-linked 误判成一次性 reveal,整个交互关系都会变。

把行为映射回自己的组件

证据链变完整以后,另一个诱惑会出现:既然已经能看到目标页面,为什么不直接把它的 CSS、结构和资源一起搬过来?

Motion Replication Kit 的硬规则正好相反。参考页面只作为不可信证据;可以复刻 motion behavior,不能复制文案、图片、品牌资产、路由或页面结构。实现时使用中性命名和本地 data attribute,把观察到的行为重新映射到自己的组件。

这个限制不是为了把事情做难。它迫使我回答一个更有用的问题:目标项目真正需要保留的,到底是哪段行为?

如果只是一次 viewport reveal,CSS transition 加 IntersectionObserver 已经够了。需要零 JS 的 scroll progress,可以把原生 scroll-driven animation 当 progressive enhancement。只有在时间线、pin、scrub 或复杂序列真的存在时,才值得把 GSAP 和 ScrollTrigger 请进来。

技术越强,不一定越接近参考。一个原本 200ms 就结束的淡入,被做成可 scrub 的大时间线,只是把简单问题复刻得更贵。

所以工具不会从“检测到 GSAP”推出“目标项目也必须用 GSAP”。检测到的库是来源线索,不是实现命令。最终选择应该由行为复杂度、目标项目已有依赖、浏览器支持和 reduced-motion 方案一起决定。

让页面在 reduced motion 下再走一遍

很多动效复刻在“看起来像”之后就结束了。这个 kit 把结束线往后挪了一点。

每个动画都要有 prefers-reduced-motion 分支,而且 reduced-motion 不是把 duration 改成 0 就算交差。内容必须处于最终可见状态,不能因为 transform 或 opacity 的初始值卡在页面外面。

Capture 可以再跑一次 reduced-motion pass,compare 会根据两组 signal 判断参考页面是 honors、ignores、mixed 还是 unknown。这里故意没有在零依赖脚本里硬做 PNG 像素比较:为了比较图片引入解码依赖,会破坏工具保持零 runtime dependency 的边界。像素回归交给目标项目里的 Playwright toHaveScreenshot,JSON compare 只负责它能可靠判断的活动信号。

性能也一样。模板会在滚动采样期间观察 long task 和 CLS,并提供可以按项目调整的起始预算。它们不是“这个动效性能很好”的证明,只是一道门:复刻出来的手感不能靠阻塞主线程和推页面布局换来。

这层验证让“像”变成了几个更具体的问题:正常模式下顺序对不对,reduced motion 下内容还在不在,filmstrip 是否保留关键阶段,滚动时有没有明显长任务和布局偏移。

我最后会停在第三帧

我刚刚在当前仓库重新跑了一次测试:5 个测试通过,0 失败,0 跳过。它覆盖 capture 基线、几类 motion inference、stagger 推断、(inferred — verify) 标记和 MCP surface。

这个结果能证明工具链在这台机器上跑通,不能证明它已经理解所有网页动效。后者没有数据,我也不打算从五个绿色勾里变出来。

Motion Replication Kit 现在更像一套给人和 Agent 共用的取证流程。它保存状态,也记录时间;产出候选解释以后,还要回到 filmstrip 或 video 复核;实现完成以后,再用 reduced motion、视觉回归和性能门把结果收住。

所以我现在的最后一道检查很具体:打开 filmstrip,停在第三帧。它能不能说明元素还在过渡、已经被 pin 住,还是跟着滚动进度走?

如果答案仍然是 unknown,实现 brief 就继续留空。需要 video,就补 video;需要 trace,就回到 trace。第三帧过不了,代码先别动。

相关文章

和这个主题相邻的更多笔记。

在早期阶段,小型内容模型往往比大型 CMS 迁移更有用

前端
2026年4月10日6 分钟阅读更新于 2026年4月12日

在内容形状真正稳定之前,一个窄而本地的 schema 往往比仓促上 CMS 更耐用。

content-modeling
mdx
typescript
阅读全文

用本地工具和云模型搭建个人 AI 工作台

精选
AI 工程
2026年5月8日8 分钟阅读更新于 2026年5月10日

一个实用的 AI 工作环境:能起草、测试和发布,又不会把流程缠在一起。

ai-agent
automation
codex
阅读全文

为技术作品集网站设计真正有说服力的案例研究

精选
产品构建
2026年5月5日6 分钟阅读更新于 2026年5月7日

怎样组织案例研究,才能证明判断力,而不只是展示结果。

portfolio
case-study
writing
阅读全文

下一步

继续浏览文章列表,或者把这篇文章里的问题展开成一次具体讨论。