mcpField
P
paper-cutout

paper-cutout

github.com/edenfunf创意与媒体1.9k55 次安装1 天前更新
代码仓库

关于 paper-cutout

用于制作纸片定格动画的 JavaScript 引擎,面向逐镜头构建动画的创作者。它以时间驱动每帧,并提供纸片材质、角色动作、转场和无头渲染流程。

主要功能

  1. 01按时间生成确定性画面
  2. 02纸片形状、材质与阴影
  3. 03角色姿势和表情控制
  4. 04镜头转场与字幕轨道
  5. 05无头生成预览及视频帧

适用场景

  1. 01制作纸片风格的定格动画
  2. 02按分镜构建逐镜头场景
  3. 03渲染联系表、片段和最终帧
  4. 04检查角色表情与动作效果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/edenfunf/reelmimic --skill paper-cutout

安装后在 Claude Code 中输入/paper-cutout确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

GUIDE.md
scripts/
new_project.sh
template/
.gitignore
LICENSE-render.mjs.txt
package-lock.json
package.json
render.mjs
studio.html
template/src/
cast.js
config.js
cutout.js
kit.js
template/src/scenes/
demo.js

详细介绍

纸片剪贴(定格纸片)引擎

每一帧都是时间 t 的纯函数。studio.html 会加载 src/kit.js(共享的 ReelMimic 运行时:时间轴、运动辅助函数、摄像机、渲染钩子)、src/cutout.js(此视觉风格:材质、剪裁/撕裂纸片、阴影、布景、道具、转场、字幕、拍摄成片效果)、src/cast.js(木偶)以及每个镜头对应的场景文件。 render.mjs 使用无头 Chrome 生成缩略图表、条带图、裁剪图和最终帧。

工作流

  1. 搭建框架 — 执行 bash .claude/skills/paper-cutout/scripts/new_project.sh <project-dir>(添加 --keep-demo 可保留示例)。然后完整阅读本技能文件夹中的 GUIDE.md,并查看 docs/demo-sheet.jpg、docs/expressions.jpg(两个木偶各有 13 种表情)和 docs/poses.jpg。
  2. 绘制分镜,并标注观众需要理解的内容及其出现时机——遵循与绘制动画相同的原则,参见 ANIMATION_GUIDE.md(时机、一次只传达一个信息、预备动作 → 动作 → 后续动作、每个衔接处都要有转场)。
  3. 构建——在 src/scenes/ 中为每个镜头创建一个 IIFE 文件,每个文件都以 shots([[t0, fn]]) 结尾;在 studio.html 中将其 <script> 添加到 cast.js 之后。在 src/config.js 中设置 duration。镜头起始时间设为 1/12 秒的整数倍。
  4. 查看效果——使用 node render.mjs --sheet=... --cols=4 --w=480 --out=out/check/a.jpg 生成缩略图表,使用 --strip=a:b 查看运动,使用 --crop=x,y,w,h / --crop-at= 查看面部和手部。用 Read 打开每张图片。修正后重新渲染。
  5. 渲染——执行 node render.mjs --frames --workers=4 && node render.mjs --encode --out=out/video.mp4 [--audio=...]。

一屏速查 API(所有角度单位为度,尺寸单位为 px,时间使用 sm(lt))

paperCam(lt, [[0,[cx,cy,zoom]], [2,[cx,cy,zoom]]], { stepped })   // camBegin with a (smooth | stepped) move
backdrop(PC.sky, { to })            layer(.5, () => ...)            // screen-fixed sheet; parallax depth plane
hills(x,y,w,h,col,{seed,torn})  grass(x,y,w,h,col,seed)  tree(x,y,s,{fruit,sway}) → {fruit:[[x,y]..]}  bush  flower
cloud(x,y,w,{hang:'string'|'stick'})  sun(x,y,r)  house(x,y,s)  bunting(x0,y0,x1,y1,n,cols)  stripes  confetti(lt,x,y,{t0})
piece(SH.xxx(...), { x,y,rot,sx,sy, col, mat, depth, torn, seed, alpha, jit })   // ONE cut-out; the base of everything
SH.ellipse/circle/rect/round/poly/smooth/capsule/blob/cloud/leaf/heart/star/drop/tri/band/zig/hills ; clipHalf ; xform
mat: 'paper' | 'card' | 'kraft' | 'felt' | 'tissue' | 'corr' | 'wood'       brad(x,y,r)  thread(pts)  popUp(k,x,y,fn)
PROPS.apple|balloon|flower|star|gift|letter(x, y, ang, s)
// transitions — call AFTER camEnd(), in the INCOMING shot, k = 0→1 on stepped time:
trBook(t,k)  trTear(t,k)  trFlip(t,k)  trSlide(t,k,{dir})  sheetIn(k)  sheetOut(k)
captionTrack([[t0, t1, '文字', { style: 'label' | 'letters', y, size }]])

// puppets (cast.js) — (x, y) = ground point, u = size unit
pom(x, y, u, opts)  lulu(x, y, u, opts)  → joints { hand:[L,R], elbow, shoulder, foot, head, top, mouth }
opts: face, view:'front'|'3q', flip, look, blink, armL/armR:[shoulder,elbow], footL/footR:[dx,dy], sq, dy, lean, tilt,
      holdL/holdR:'apple'|{prop,s,dy}|fn, jit, dry (measure only)
moods(lt, [[0,'sad'],[2,'surprised']])  walkCycle(lt,{stride,rate}) + walkSpeed()  jumpPose(lt,t0,t1,h)  emote(kind,x,y,s,age)
EXPR: neutral happy laugh sad cry angry surprised scared love sleepy wink determined shy

最重要的规则

  1. 所有东西都是纸片。 只能通过 piece() / 辅助函数绘制(场景中绝不能直接使用 fillRect/arc)。为每个对象选择一种材质;景观和标签使用撕裂边缘,角色和道具使用剪刀剪出的边缘。
  2. 深度 = 阴影。 背景图层的 depth 为 .3–.8,布景约为 1,木偶为 1–1.3,漂浮/举起的物体为 1.5–3。使用 layer(k) 实现视差。绝不要伪造 3D 效果。
  3. 定格动画时序。 使用 sm(lt) 驱动每个木偶/道具的姿势(每秒 12 步)。木偶每步会自动轻微抖动;布景应保持固定(jit: 0)。摄像机运动可以平滑(运动控制)或采用 stepped。
  4. 替换式表情。 使用 moods() 更换表情(眨眼会隐藏切换过程),不要逐帧翻转 face。
  5. 每个衔接处都要使用工具包提供的四种转场之一(书本折页、撕裂显现、翻转卡片、纸张滑动);如果下一个镜头使用其中一种转场,前一个镜头就不能绘制自己的出场转场,因为转场会实时重新渲染前一个镜头。
  6. 手机屏幕上也要清晰可读: 木偶要够大(中景中 pom 的 u ≥ 55,lulu 的 u ≥ 36),字幕 ≥ 70 px。
  7. 字幕只能通过 captionTrack 添加(覆盖层,CJK 字体依次使用 "Chiron GoRound TC" → "Zen Maru Gothic" → "Noto Sans TC")。

引擎注意事项

  • t 的纯函数:不能使用 Math.random(),帧与帧之间不能保留状态。使用 hash/rnd/sway(key)。
  • piece() 会按形状键 + seed 缓存剪裁轮廓。为每张不同的纸片指定独有的 seed,否则两个相同形状会出现相同的晃动(用于彩纸没问题,但一对树看起来就很奇怪)。
  • 剪裁轮廓取决于形状尺寸,因此尺寸动画会导致每帧重新剪裁(边缘会闪烁)。应通过 sx/sy 或摄像机缩放,而不是动画改变形状尺寸。
  • prevFrame() 会在当前时间渲染前一个镜头(转场期间前一个镜头会继续运动),并替换 G;场景必须使用 G,不能使用捕获的上下文。
  • 翻转的木偶所持道具会自动取消镜像(文字/不对称道具仍保持可读)。
  • 速度:每帧绘制约需 5–30 ms;在 1920×1080 分辨率下,包含 JPEG 编码且使用 4 个工作线程时,实际约为 130 ms/帧。

评论

支持 Markdown