Communitygithub.com

kinqsradio/motion-match

复制、克隆或匹配动画效果:测量时序与缓动,编写规格说明,构建实现,以相同方式录制我们的版本并持续对比,直到数值达标;第三方参考仅限运动层面。使用 orbyn-ui-design 设计动效,technical-illustration 制作影片,product-illustration 制作伪 UI。

motion-match 是什么?

Motion-match 是一个 AI 代理技能,专为需要精确匹配或验证 UI 动效的开发者设计。其核心目标是将“看起来差不多”的模糊判断替换为可量化、可重复的数值验证流程。该技能支持三种保真度级别:运动级(默认,仅匹配时序、缓动等运动属性)、像素级(仅限自有或许可资源,匹配所有视觉属性)和混合级。工作流程从确定版权归属开始,通过录制参考动画、逐帧分析并生成规格说明,然后在项目中构建实现,最后录制并自动对比,迭代优化直到所有数值指标通过。该技能依赖于 Node 22、Playwright 和 Chrome 浏览器驱动;对于视频素材,还需要 ffmpeg。它明确区分了可接受的参考使用范围:对于第三方素材仅提取运动特征(时序、缓动、顺序和距离),绝不复制任何代码、设计资产或布局。最终的交付物是代码、数值表格和分析图表,确保动画效果准确无误。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/kinqsradio/orbyn-fullstack-skills/tree/HEAD/skills/motion-match

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

运动匹配

当用户指着某个运动元素,希望我们的实现与之相同,或需要证明两者一致时使用此技能。最终交付的是代码、数值和图表,而非“看起来差不多”。

版权优先

在录制任何参考之前,先确定其版权归属,并在第一条消息中声明。

参考来源允许的操作
我们自己的作品,或用户拥有/已授权的作品任何保真度,包括像素级
任何其他人的网站或视频仅测量时序、缓动、顺序和距离,以书面规格记录,并用我们自己的设计构建

对于其他人的作品:

  • 绝不复制他们的代码、着色器、资源、字体、品牌、布局或文案。绝不将真实产品冒充为我们的。
  • 无论请求如何表述,像素级精确匹配都不可行。建议改为运动级匹配,并说明原因:“我可以匹配其运动方式,应用你的设计。复制他们的外观会占用他们的设计成果,所以我不会这么做。”
  • 登录墙、付费墙、机器人检测和 DRM 保护内容应保持原样。遵守网站条款,仅捕获普通访客可见的内容。当页面无法访问时,请用户提供屏幕录制。绝不下载他人的视频。
  • 原始录制文件保存在 Git 忽略的本地文件夹中。它们绝不会被提交、发布或用于交付物,并在用户同意后删除。仅保留书面数值。告诉用户文件位置。

若用户声称拥有参考版权且无矛盾之处,则采信用户说法,并在规格中记录。“让它与那家公司的网站一模一样”并不构成授权。当版权不明确时,使用 --rights third-party。

保真度

在第一条消息中声明保真度级别;它决定了验证内容。

级别必须匹配可以不同
运动(默认)触发器、顺序、交错、每一步的时序(80 ms 内)、缓动、方向和距离文案、颜色、字体、图片、布局、品牌
像素(仅限自有或许可资源)以上所有项目,外加字体、字号、颜色、间距和资源;平均差异最多 2%用户未要求更改的任何内容
混合匹配部分,按上述级别之一新增部分,不得破坏已匹配的运动

仅匹配用户指定的内容:一个区块、一个组件或一个时间范围。

方法

在 output/motion-match/<name>/ 或 Git 忽略的其他目录中工作。保留每一轮的结果。需要 --playwright 和 --chrome 参数,或设置 PLAYWRIGHT_CORE 和 CHROME_PATH 环境变量。需要 Node 22、现有浏览器驱动和浏览器;视频处理需要 ffmpeg。不会安装任何其他依赖。

  1. 范围界定。 明确目标对象、项目中的位置、版权归属和保真度。

  2. 录制参考,使用 scripts/capture.mjs(网页)或 scripts/frames.mjs(已有视频)。传入你确定的版权参数:

    node <skill>/scripts/capture.mjs --url <页面> --out <目录>/ref --rights third-party \
      --selector .hero --track ".title, .cta" --duration 2000
    
  3. 阅读每一张图表。 运行 scripts/sheet.mjs filmstrip,然后打开每一张图表。缓动信息位于中间帧。

  4. 编写规格说明。 运行 scripts/spec.mjs draft:每个元素每个属性一行。? 表示尚未完成帧分析,检查命令将拒绝运行,直到每个 ? 被替换。

  5. 构建项目,使用项目自身的开发栈。若参考为第三方素材,则使用项目自己的设计。

  6. 以相同方式录制我们的版本。 复用参考命令,仅更改 --url、--out 和 --rights。不同的设置会测量你的环境差异,导致 compare.mjs 失败。

  7. 对比。 依次运行 scripts/spec.mjs check、scripts/compare.mjs 和 scripts/sheet.mjs compare。阅读每一张图表。

  8. 根据数值指向的最小问题,每次修改一个原因,然后返回步骤 6。

  9. 若 5 轮后仍有行未通过,则报告该行及其数值和原因。保持阈值不变。

  10. 报告,确保消息独立完整:版权和保真度;匹配和新增的内容;文件路径及如何触发动画;最后一轮的表格;图表路径;每个残留问题的数值和原因;以及任何原始第三方录制的存放位置。

失败示例

三轮卡片中第一轮失败:

.card-1 opacity  start +300 ms  end +300 ms  easing RMSE 0.0003  FAIL
.card-2 opacity  start +300 ms  end +300 ms  easing RMSE 0.0055  FAIL
gaps             116.7 against 116.7         pass

每一行都延迟了相同的量,且曲线和间距正确,因此唯一原因是基础延迟。修改这一个数值并重新录制。对齐帧会让这行通过,但会交付一个延迟 300 ms 的动画,这就是为什么 compare.mjs 在两个录制之间拒绝 --auto-align 参数。

常见陷阱

  • 两侧视口或裁剪区域不同:在修改代码之前修复录制。
  • 仅凭首帧和尾帧判断:要阅读中间帧。
  • 字体:后备字体每一帧的像素都会变化。在运动保真度下,读取时序行并忽略文字像素。
  • 页面在冷启动时已处于繁忙状态:两侧使用相同的 --wait-before。
  • 滚动驱动动画跟随滚动位置而非时间:两侧使用相同的 --scroll-steps 和 --scroll-ms,并按 scrollY 比较。
  • 弹簧动画:easing.mjs 报告过冲、拟合刚度和阻尼。根据过冲和稳定时间进行调整。
  • 屏幕录制包含光标、浏览器界面和压缩噪声。裁剪掉这些区域,并稍微提高 --activity-threshold。
  • Canvas 内容:两侧使用虚拟时钟和相同的 --seed。使用真实时钟的随机内容测量的是机器性能。
  • CSS 动画在 timing.easing 中报告为 linear。实际的缓动位于每个关键帧上。

边界

使用 orbyn-ui-design 决定产品应使用的动效,使用 technical-illustration 制作影片,使用 product-illustration 制作伪 UI。视频遵循 纯代码规则:可以将参考视为技术学习的对象,但绝不复制其帧。

需要时阅读

  • 关于录制方式、触发器和输出文件,阅读 capture。
  • 关于规格格式和如何阅读帧,阅读 analysis。
  • 关于缓动、弹簧和构建模式,阅读 implementation。
  • 关于通过标准和每个失败的含义,阅读 verify。

相关技能