关于 scenario-motion-loops
scenario-motion-loops 是用于制作可循环 Canvas 2D 动画的技能,面向需要可编辑品牌动效和视频输出的创作者。它以时间确定性绘制画面,并通过检查验证循环接缝和渲染结果。
主要功能
- 01单 HTML 文件绘制动画
- 02确定性时间驱动帧
- 03检查循环接缝与一致性
- 04渲染静帧和 MP4
- 05支持透明 PNG 叠加
- 06适配多种画面比例
适用场景
- 01制作品牌色循环背景动画
- 02将透明主体合成到循环画面
- 03检查现有 MP4 的循环接缝
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-motion-loops安装后在 Claude Code 中输入/scenario-motion-loops确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/loop-craft.mdscripts/loop-template.htmlrender-loop.mjs详细介绍
Scenario 动效循环
概述
循环是时间的纯函数,在一个 HTML 文件中使用 Canvas 2D 绘制。内容不会生成,因此不会变形或闪烁;只需更改一种颜色即可重新打造品牌效果,而且可以按任意尺寸渲染。
draw(ctx, w, h, t, P)绘制t秒时的画面。每个周期都能整除 12 s,因此 12 s 时的画面与 0 s 时相同。- scripts/loop-template.html 包含辅助函数(
M.*)、调色板(P)和tile(...)注册。来自 scenario.com Motion Loops 探索项目的 Tile(80 个循环,每个都附有代码)可直接运行,无需修改。 - scripts/render-loop.mjs 会检查页面、渲染静帧或 MP4,并检查编码后的文件。
- Scenario 只负责生成主体:带 alpha 通道的抠图 PNG,可以是吉祥物、产品或角色。页面会根据循环时钟绘制主体,因此合成画面保留动态模糊并保持循环。循环本身无需任何生成,也不产生费用。
需要 Node 18 或更高版本、带有 ffprobe 的 ffmpeg 5.1 或更高版本,以及脚本运行环境中安装的 Playwright(运行 npm install playwright,然后运行 npx playwright install chromium;如果已安装 Google Chrome,也可使用 --channel chrome)。连接、模型发现、上传和定价信息:请参阅 scenario 技能。抠图:scenario-image-editing。视频镜头:scenario-video,背景移除:scenario-video-editing。如果你可用的技能中缺少此处提到的同系列技能,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);无人值守时,请根据工具架构继续操作,并标记这一缺口。
快速参考
cp scripts/loop-template.html loop.html # one loop per file: settings, draw(), overlay
# open loop.html in a browser to preview; ?t=3 freezes it, ?tone=accent or ?tone=light switches tone
node scripts/render-loop.mjs loop.html --check # determinism and loop seam, no video
node scripts/render-loop.mjs loop.html --stills look --at 0,3,6,9 # stills to look at
node scripts/render-loop.mjs loop.html --out loop.mp4 # 12 s, 1920x1080, 24 fps
node scripts/render-loop.mjs loop.html --params "overlay=subject.png" --out loop.mp4 # with a cut-out
node scripts/render-loop.mjs loop.html --width 1080 --height 1920 --out loop-9x16.mp4 # vertical
node scripts/render-loop.mjs --qa loop.mp4 composite.mp4 # seam and format check of any MP4
- 请在已安装 Playwright 的文件夹中运行。除非使用
--force,否则绝不会覆盖现有文件。 - 页面检查会将同一时刻渲染两次(两次结果必须一致),并比较恰好 12 s 时的画面与 0 s 时的画面。它还会比较循环交界处的步进与交界处周围的运动,以及每个周期边界处的情况。
- 只有检查结果显示
PASS,才会进行编码。--ignore-seam仅适用于设计为在循环交界处剪切的片段;它会免除两项检查中的交界处判定。 - 默认值,即随 80 个循环提供的设置:24 fps、以 180 度快门进行 8 次动态模糊子帧采样、2 倍超采样、H.264 High、CRF 16、4:2:0、BT.709 有限范围、faststart。
- 编写本文时,完整渲染 1080p 约需 6 分钟(每帧约 1.3 s)。请设置较长的超时时间,或在后台运行。
每个 Tile 都遵循以下规则:
- 周期:每个周期都能整除 12 s(1、1.5、2、3、4、6、12)。使用
M.phase(t, period, offset)。 - 滚动:每个周期移动整数个图案重复单元;重复单元数量为小数时,交界处会跳变。
- 随机性:只能使用
M.rand(i, salt)。不要使用Math.random、Date或跨帧保留的状态:动态模糊和检查会以乱序方式渲染帧。 - 单位:尺寸根据
u = h / 100计算,数量根据w计算,因此循环在 16:9、9:16、1:1 和缩略图尺寸下都能正常显示。 - 颜色:只能使用
P中的颜色(bg、fg、fg2、mid、accent、paper、ink)。通过更改BRAND来重新打造品牌效果;通过更改色调(dark、accent、light)来调整对比度,绝不要添加颜色。 - 多色调循环:彩虹或色相扫掠是唯一例外。使用周期能整除 12 的设置,将色相计算为
hsl(${360 * M.phase(t, 12)}, ...),并将其设置保存在BRAND中,以便仍可在同一处重新打造品牌效果。 - 缓动:使用
M.ease,并加入预备动作、过冲和停顿。只有滚动和流动效果可以保持恒定速度。
关于闭合循环的图案、不借助 3D 引擎营造景深,以及评审习惯,请参阅:
references/loop-craft.md。编写新的 draw() 之前请先阅读。
操作示例:在编码循环上方漂浮的品牌吉祥物
目标:制作一个 12 s、1920x1080 的无缝循环动画,使用品牌色,并让品牌吉祥物在其中漂浮; 还可选择制作一个吉祥物挥手的版本。
-
先构建循环动画(本地、免费)。
cp scripts/loop-template.html mascot-loop.html,将BRAND.accent设为品牌色,并保留示例图块(Perspective Floor,一种朝摄像机方向延伸的网格), 或自行编写draw()。然后:node scripts/render-loop.mjs mascot-loop.html --check node scripts/render-loop.mjs mascot-loop.html --stills look --at 0,3,6,9--check必须以PASS结束。查看静帧。 -
制作抠图。 连接并根据
scenario技能选择团队和项目。如果用户提供了吉祥物文件,则上传该文件。使用以下内容调用recommend:{ "capability": "img2img", "prompt": "The mascot from the reference image, full body, three-quarter view, a light floating pose, cut out on a transparent background with clean edges, no shadow, no text", "limit": 5 }如果没有文件,请使用
"capability": "txt2img"并描述吉祥物。优先选择model_schema_get架构支持透明背景的成员。否则,之后按照scenario-image-editing移除背景。使用dry_run估算价格,并等待用户确认。 无人值守时,仅在任务指定的预算内运行;否则停止并报告价格。然后使用asset_download并设置"format": "png",再运行curl -L -o subject.png "<url>",将文件保存到mascot-loop.html所在文件夹。 -
检查抠图。 在循环动画的背景色上以 100% 缩放查看 PNG。深色调背景上会显露轮廓边缘的光晕:重新生成,不要试图隐藏。背景移除工具的架构通常有边缘或阈值设置:重新运行时调高该设置。
-
在画布中合成并渲染。
node scripts/render-loop.mjs mascot-loop.html --params "overlay=subject.png" --stills look --at 0,0.75,1.5,2.25 --force node scripts/render-loop.mjs mascot-loop.html --params "overlay=subject.png" --out mascot-loop.mp4 --psnr 4页面中的
drawOverlay()会让主体以 3 s 的上下浮动和 6 s 的摇摆漂浮,并添加接触阴影,因此合成结果仍可循环播放。在此处调整大小和位置。脚本会检查页面、渲染 288 帧、编码,并检查文件的循环衔接点。--psnr会将一帧编码结果与其无损渲染进行比较。 -
可选:制作吉祥物移动的镜头。
- 按照
scenario-video生成:从抠图使用img2video,提示词为 "the mascot waves and turns its head, plain flat background, locked-off camera, no cuts"。纯色背景和固定摄像机可让背景移除更干净。 - 按照
scenario-video-editing移除其背景,选择带 alpha 通道的 WebM VP9(用于编辑软件时选择 ProRes 4444)。 - 不带叠加层渲染循环动画(
--out loop-plain.mp4),然后将镜头叠加到其上:
ffmpeg -stream_loop -1 -i loop-plain.mp4 -c:v libvpx-vp9 -i shot.webm \ -filter_complex "[1:v]fps=24,scale=-2:720[s];[0:v][s]overlay=(W-w)/2:(H-h)/2:shortest=1,format=yuv420p,setparams=colorspace=bt709:color_primaries=bt709:color_trc=bt709:range=tv" \ -c:v libx264 -crf 16 -preset slow -colorspace bt709 -color_primaries bt709 -color_trc bt709 \ -color_range tv -movflags +faststart -an composite.mp4合成时长与镜头时长相同。除非镜头本身可循环,否则合成结果并非无缝循环:对任何预期循环播放的内容运行
--qa。 - 按照
-
交付 HTML(循环动画仍可编辑)、MP4、静帧和任何合成文件。
常见错误
- 在 12 s 处出现接缝跳变。 周期无法整除 12(例如 5 s 的循环),或滚动距离为 2.5 次重复内容。
--check会报告SEAM JUMP。修正周期;绝不要交叉淡化首尾。 - 在图块中使用状态、
Math.random或Date。 相同的t会生成不同帧,循环也就无法闭合。--check会报告NOT DETERMINISTIC。 - 使用只能读取 hex 的颜色辅助函数。
P.mid和M.mixColor会返回rgb()字符串,而只支持 hex 的解析器会静默地将它们变成黑色。请使用模板中的M.rgba和M.mixColor。 - 快速移动时出现闪烁。 整帧推移时,8 个子帧会显示出阶梯状的重影;有一段全页滑动需要 40 个子帧。对于非常快的循环,请提高
--samples。 - 把每个标记都当成错误。 设计好的突变效果(例如弹出或爆发)或循环点处的停顿,可能会触发接缝检查。修改代码前先查看帧。
- 计数器循环错误。 所有按循环索引的内容都要使用
M.mod循环,否则循环点处会显示“06 / 05”。 - 字体加载前就绘制文本。 Canvas 文本不会等待 Web 字体加载:请在首帧前等待
document.fonts.load(...),或不绘制文本。 - 从
file://打开页面进行渲染。 本地叠加图像会污染 canvas,导致读取失败。render-loop.mjs会通过本地地址提供文件夹服务;浏览器预览不受影响。 - 一味追求比特率。 纯色画面文件看起来很小,但编码器几乎不会造成损失。真正的损失来自细窄高饱和线条上的 4:2:0 色度抽样:使用
--psnr检查,并加粗这些线条。 - 不使用
setparams就设置颜色标记。 在 ffmpeg 7 中,仅使用-colorspace、-color_primaries和-color_trc会导致原色和传递特性没有标记。像这里的两个命令一样,以setparams结束滤镜链;否则--qa会报告UNTAGGED COLOR。 - VP9 视频片段的 alpha 通道丢失。 ffmpeg 内置的 VP9 解码器会忽略 alpha,导致视频片段被黑框包围。请将
-c:v libvpx-vp9放在-i shot.webm之前。ffprobe 会将这类文件报告为yuv420p,且alpha_mode=1;文件仍然包含 alpha 通道。 - 用视频模型制作循环。 生成片段的最后一帧很少能与第一帧衔接。请用代码制作循环;使用 Scenario 生成主体。