Communitygithub.com

MotionCraft Builder

像精品工作室一样构建电影级动效网站:从客户世界的单一概念出发,生成可滚动的 Three.js 场景、电影级首屏、视差深度照片、合成音效和实时 3D 标注。

MotionCraft Builder 是什么?

这是一个用于构建高级动效网站的 AI 技能,它指导 AI 代理遵循精品工作室的工作流程:从客户真实世界的单一概念出发,依次完成想法提炼、页面架构选择、节奏表编写、灰盒机制搭建、内容装饰、审查修复和最终交付。它默认使用纯语义 HTML、CSS、Vanilla JavaScript 模块和 Three.js 0.170(通过 import map),无构建步骤,仅在需要时添加 GSAP 或 Lenis。该技能适用于 Claude Code、Cursor 等支持自定义技能和 Markdown 文档的 AI 编码工具。它强调每一步都有可展示的产出,确保页面在关闭 WebGL 后仍能正常阅读和转化。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/iboss21/regescore-motioncraft-skills/tree/main/plugins/motioncraft/skills/motioncraft-builder

在你喜欢的 AI 中提问

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

文档

MotionCraft Builder 是做什么的?

该技能教导 AI 代理像精品工作室交付获奖作品一样构建动效网站:一个想法、一份书面计划、一个灰盒中的工作机制、然后进行装饰,最后严格审查并修复。工艺精髓在于参考资料。本文件即是工作流程。

默认技术栈: 语义 HTML、CSS、Vanilla JavaScript 模块、通过 import map 引入的 Three.js 0.170,无构建步骤。仅在配方需要时添加 GSAP 或 Lenis。每个页面必须在关闭 WebGL 的情况下也能正常工作、可阅读并实现转化。

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
  }
}
</script>

工作流程

按顺序执行以下步骤。在展示给客户之前,不要跳到效果实现。每个步骤都有可以展示的产出。

步骤 1. 找到单一概念

阅读简报,列出客户的真实世界:他们处理的物体、打印的文件、场所的声音、员工整天使用的动词。然后写一句话:

[品牌] 是一个网站,你在其中 [动词] 来自他们世界的 [物体],它会向你展示 [他们销售的价值]。

虚构品牌示例:

  • Cinderford Coffee Roasters:你滚动一颗咖啡豆经历烘焙过程,从绿色到一爆再到全城,随着颜色变化,风味笔记会打印在烘焙日志上。
  • Lakemont Bike Fitters:你拖动骑手的坐垫高度,膝盖角度弧线会在实时侧视图中重新绘制。
  • Halvorsen Tide Charters:你滑动潮汐时钟,船只会在真实码头前上下浮动。

概念规则(参见工艺规则 1 至 3):

  • 一个物体,一个动词,一个世界。如果你需要两次“并且”,那就是两个概念,选其中一个。
  • 隐喻必须来自客户的世界,而非来自潮流。车库用维修单说话,杂货商用每周传单说话,交通机构用线路图说话。
  • 给强调色一个任务。如果红色表示“发现故障”,那么它在页面任何其他位置都别无含义。
  • 加载器、光标、导航、悬停状态、过渡效果和 404 页面都必须使用同一种语言。

产出: 该句话、动词、强调色及其含义,以及三个被否决的概念(每个附带一行落选原因)。

步骤 2. 选择页面架构

打开 page-architecture.md。选择与概念同源的导航原型、首屏构成和区块序列。切勿重用前一个项目的骨架。将选择记录在项目 README 中,以便后续构建避免重复。

产出: 一个简短的架构卡片(导航、首屏、区块列表、页脚、404),注明所使用的命名模式。

步骤 3. 编写节奏表

在任何代码之前编写剧本。使用 beat-sheet.md 中的模板。每个节拍需说明其滚动范围、访客所见内容、移动元素、文案、摄像机、手机构图、减少动效版本及成本。示例展示了期望的详细程度。

产出: 填写完整的节奏表。后续所有决策都以此为准绳。如果某个区块不为步骤 1 中的那句话服务,在此处删除它——此刻删除成本最低。

步骤 4. 灰盒化机制

使用占位几何体和占位文案构建动效。此步骤在任何素材存在之前验证时序、相机和交互。

  1. 优先编写 DOM:真实的标题、真实的文案块、真实的按钮和表单,每个节拍对应一个 <section class="shot">。页面必须在脚本关闭的情况下从上到下可读。
  2. 在 DOM 后方添加一个固定画布和一个渲染循环。滚动、指针、音频和渲染共享同一个循环(规则 8)。
  3. 将滚动映射为一个单一的浮点数 t,用于计数节拍,并通过一个带有平滑插值的镜头列表移动摄像机(滚动与相机配方)。
  4. 所有对象均使用灰盒子、球体和平面。如果故事在灰盒状态下无法正常工作,装饰也无法挽救。
  5. 立即添加暂停控制和减少动效分支,而不是在结束时(交互配方)。

灰盒起始模板。页面需要上述 import map、一个固定画布以及每个 SHOTS 条目对应的 .shot 区块:

<style>
  #gl { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; display: block; }
  .shot { min-height: 100svh; display: grid; align-items: center; padding: 16px 6vw; }
  .no-gl #gl { display: none; }
</style>
<canvas id="gl" aria-hidden="true"></canvas>
<main>
  <section class="shot" id="top"><h1>来自节拍 0 的标题</h1></section>
  <section class="shot" id="detail"><h2>节拍 1</h2></section>
  <section class="shot" id="side"><h2>节拍 2</h2></section>
</main>
<script type="module" src="main.js"></script>

main.js:

import * as THREE from "three";

const canvas = document.getElementById("gl");
let renderer = null;
try { renderer = new THREE.WebGLRenderer({ canvas, antialias: true, powerPreference: "high-performance" }); }
catch { document.body.classList.add("no-gl"); } // DOM 页面独立存在

if (renderer) {
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0x111114);
  scene.add(new THREE.HemisphereLight(0xffffff, 0x222233, 1.4));
  const camera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);
  // 在节奏表签署之前,使用灰色占位物代替首屏对象
  scene.add(new THREE.Mesh(new THREE.BoxGeometry(2, 1, 1.2), new THREE.MeshStandardMaterial({ color: 0x8a8a8a, roughness: 0.6 })));

  const V = (x, y, z) => new THREE.Vector3(x, y, z);
  const SHOTS = [
    { pos: V(4, 3, 8), at: V(-1.5, 0, 0) },  // 首屏:对象位于标题右侧
    { pos: V(0, 9, 0.1), at: V(0, 0, 0) },   // 俯视细节
    { pos: V(-6, 1.2, 3), at: V(1.5, 0, 0) }, // 低角度侧面,文案在右侧
  ];
  const sections = [...document.querySelectorAll(".shot")];
  let centers = [];
  const measure = () => { centers = sections.map((s) => s.offsetTop + s.offsetHeight / 2); };
  const smooth = (a, b, x) => { const k = Math.min(1, Math.max(0, (x - a) / (b - a))); return k * k * (3 - 2 * k); };
  function scrollT() {
    const c = scrollY + innerHeight / 2;
    if (!centers.length || c <= centers[0]) return 0;
    for (let i = 0; i < centers.length - 1; i++) if (c < centers[i + 1]) return i + (c - centers[i]) / (centers[i + 1] - centers[i]);
    return centers.length - 1;
  }
  function resize() {
    renderer.setPixelRatio(Math.min(devicePixelRatio, innerWidth < 760 ? 1.5 : 1.75));
    renderer.setSize(innerWidth, innerHeight, false);
    camera.aspect = innerWidth / innerHeight;
    camera.updateProjectionMatrix();
    measure();
  }
  addEventListener("resize", resize);
  document.fonts?.ready.then(measure);
  resize();

  const pos = new THREE.Vector3(), at = new THREE.Vector3();
  let raf = 0;
  function frame() {
    raf = requestAnimationFrame(frame);
    const t = scrollT(), i0 = Math.floor(t), i1 = Math.min(SHOTS.length - 1, i0 + 1);
    const f = smooth(0.15, 0.85, t - i0); // 在每个镜头处保持,在中间过渡
    pos.lerpVectors(SHOTS[i0].pos, SHOTS[i1].pos, f);
    at.lerpVectors(SHOTS[i0].at, SHOTS[i1].at, f);
    camera.position.copy(pos);
    camera.lookAt(at);
    renderer.render(scene, camera);
  }
  raf = requestAnimationFrame(frame);
  document.addEventListener("visibilitychange", () => {
    cancelAnimationFrame(raf); // 绝不允许两个循环同时运行
    if (!document.hidden) raf = requestAnimationFrame(frame);
  });
}

步骤 4 退出标准: 向前和向后滚动经过每个节拍,摄像机在两个方向上应一致对齐;每个镜头都为其文案留有空间;手机构图在 390 x 844 分辨率下工作正常;暂停控制停止所有持续运动;关闭 WebGL 后页面可读。

步骤 5. 装饰

现在用真实世界替换灰色。从技术索引中提取配方。按以下顺序进行装饰,每层完成后对比节奏表进行检查:

  1. 形态: 首屏对象,由基本几何体、glTF、影片或深度照片构建。
  2. 光照: 主光、轮廓光和一束动机明确的强调光。任何放置在表面上的物体下方都需要接触阴影。
  3. 材质与纹理: 在照片纹理之前优先使用 Canvas 绘制的标签和面板。它们清晰、微小且可编辑。
  4. 字体: 最多两种字体。标题动效应与页面节奏相关联,避免使用通用的淡入淡出效果。
  5. 音效: 可选、需用户选择加入、使用 Web Audio 合成以节省字节。
  6. 小彩蛋: 一个隐藏手势、一个空闲状态、一个使用品牌语言的 404 页面。

将帧时间花在交互上,而不是无人注意的物理效果上。模拟昂贵的部分(规则 17)。

步骤 6. 检查并修复

在审查之前,你尚未完成。将页面交给 motion-review 技能(../motion-review/SKILL.md)进行评分、QA 检查清单以及桌面和手机尺寸的截图;同时交给 motion-analytics 技能(../motion-analytics/SKILL.md)进行帧时间、页面权重和参考对比评分。然后修复最先发现的最严重的错误,并再次审查。对于任何你称之为“完成”的作品,至少需要进行两次完整的检查与修复循环。

正式审查前的快速自查:

  • 向下滚动,然后一路滚回顶部。每个显现效果必须能干净地反向。
  • 在动效过程中按下暂停控制。所有持续运动必须停止,且页面看起来仍然完整。
  • 在操作系统中开启“减少动效”。页面必须使用静态画面讲述相同的故事。
  • 打开控制台。零错误,零由你造成的警告。
  • 手机宽度 390 px:无小于 11 px 的文字,无小于 44 px 的点击目标,无水平滚动。

步骤 7. 交付

交付页面文件夹(index.html、style.css、main.js 及其模块、assets/)、一个包含一句话概念、架构卡片、节奏表、带有许可信息的素材列表以及值得调整的调优值的 README 文件。整个页面大小控制在 10 MB 以内。

不可妥协事项

  • 底部必须有真实 HTML。内容、导航和表单位于 DOM 中。WebGL 是一种增强,需有 no-gl 降级方案。
  • 单一时钟。切勿将逐帧值放入框架状态。使用普通变量、uniforms 和 CSS 自定义属性。
  • 任何运行超过 5 秒的动效都必须有可见的暂停控制,以及完整的 prefers-reduced-motion 分支。
  • 绝不劫持滚动。原生滚动条、键盘滚动和锚点链接都必须正常工作。
  • 演示中使用虚构品牌和虚构人物。绝不从参考站点复制代码、复制文字、素材或首屏概念。研究其概念,自行编写。
  • 页面中的所有数字(价格、时间、统计数据)都必须合理、一致,并符合客户所在地的格式。

参考资料索引

文件使用场景
references/craft-rules.md做出任何关于品味的判断时。30 条带有具体数值的编号规则。
references/beat-sheet.md规划故事时。包含模板和示例。
references/page-architecture.md选择导航、首屏和区块,避免模板雷同。
references/techniques/INDEX.md按需求、成本或惊艳程度查找配方。
techniques/scroll-and-camera.md滚动映射、摄像机镜头、手机构图、模式值。
techniques/scene-craft.mdthree.js 装饰:标注、变形、城市、天空、标签、阴影。
techniques/film-and-photo.md视频首屏、循环、与影片同步的文案、跟踪热点、深度照片。
techniques/sound-and-rhythm.mdWeb Audio 语音、调度、与节拍同步的视觉。
techniques/interaction-and-access.md暂停控制、锚点、保持门控、拖拽视图、质量分级。

属于 RegesCore AI MotionCraft Skills,由 LIKE A KING INC. 制作。免费动效模板和完整目录请访问 animatedwebs.com。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相关技能