1仕組みと動作原理
コアメカニズムは SVG stroke draw-on です。パスの `stroke-dashoffset` を全長から 0 まで縮めることで、視覚的に始点から終点まで描かれる効果を生み出します。`pathLength="1"` で正規化することで、実際の長さに関わらずあらゆるパスを同一の 0→1 進捗値で制御できます。
A path "draws itself" by animating `stroke-dashoffset` from its full length down to 0 — the dash gap shrinks, exposing the stroke from start to end.
「ペン先に追従する手」がこのイリュージョンの核です。毎フレーム `getPointAtLength(len*k)` からペン先の座標を取得し、手のペン先オフセット `NIB` をその点に合わせます。`dashoffset` と手の位置はまったく同一の進捗値 `k` で駆動する必要があり、そうでなければ両者が互いに追いつかなくなります。
`getPointAtLength(len * k)` is the workhorse: it returns the on-path coordinate at the same progress driving `strokeDashoffset`, so the nib stays glued to the growing stroke.
テンポは固定タイマーではなくナレーションによって駆動されます。各描画セクションの合計時間は対応する VO(音声)行の長さ(ベースライン ~2.3 単語/秒)とほぼ一致し、ナレーションで読み上げられたラベルはその単語が発声された瞬間に描き終える必要があります。
Draw-on duration should track the spoken line, not a fixed timer.
描画順序は「人間が実際にどう描くか」に基づいて組み立てられます。SVG 内のストロークは描画順に並べられ、ドキュメント順にアニメーション化されます。要素はナレーションの順序に沿って1つずつ出現し、各ストローク完了後は 0.4〜1.0 秒の静止時間を設け、手は空中に静止せずボードから離れるようにします。
| Hold | pause hand off-board after element completes (0.4–1.0s) |
素材はあらかじめ単一ストロークの開いたパスに変換する必要があります。塗りつぶし領域にはアニメーション化できる stroke がないため、まず輪郭を描いてから塗りを追従させる手法をとります。手書き文字は、ストロークフォントをパス化して読む順に1文字ずつ描くか、矩形マスクのスイープで擬似的に手書きを再現します。
Draw-on animates strokes, not fills.
盤面にはクリア機構が必要です。消去/遷移には3つの手法(`clip-path` または白矩形による消去、逆方向 draw-on による巻き戻し、フェードアウト後の再描画)が用意されており、画面が乱雑に重なり合わないよう全編で統一された消去文法を要求します。
Keep one clear grammar (always wipe left-to-right, say) so transitions feel deliberate.
納品物 = 単一ファイル HTML(描画順のインライン SVG パス、インラインまたは data-URI の手の素材、単一のインライン script マスタータイムライン)+ `?t=N` 静止化。検証では必ず「あるストロークの途中」のタイミングを最低1点取得する必要があります。そこがペン先の追従イリュージョンが成立しているか破綻しているかを分けるポイントだからです。
Pick at least one `t` in the *middle of a stroke* — that is where the hand-on-tip illusion is proven or broken.
完成動画が必要な場合は、同一の draw-on メカニズムを Remotion に移行します。`useCurrentFrame()/fps` で `strokeDashoffset` と手の transform を同時に駆動し、フレーム単位で確定的なレンダリング(タイマーや `rAF` を使わない)を実現します。
Drive both `strokeDashoffset` and the hand transform from `useCurrentFrame()` so the render is deterministic — no timers, no rAF.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| cli | npx / Playwright(无头截图) |
| cli | ffmpeg(contact-sheet.sh 拼图) |
| cli | npx -y playwright(仓库根 seek-shot.sh 内部) |
| package | GSAP 及其 DrawSVGPlugin / MotionPathPlugin(reference 以裸包名 import,未指定 CDN) |
| network | 手写字体(Caveat / Patrick Hand / Shadows Into Light 等),来源由使用者决定(@font-face 自托管或字体 CDN) |
| api | 无第三方业务 API;旁白由使用者自备或宿主侧 TTS 产出 |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: npx playwright screenshot --wait-for-timeout=500 …(SKILL.md Verify loop 内のインラインコマンド)
- 网络端点: 外部ネットワークアクセスの宣言: スキル自体にビジネス API 呼び出しはありません。ネットワーク露出はツールチェーンに起因し、npx が registry.npmjs.org から playwright パッケージを取得し、Playwright ブラウザバイナリをダウンロードします
- 本地工作目录: ファイル読み書きと成果物の出力: frame-mid.png(SKILL.md 内のインラインスクリーンショット例の出力)、frame-<t>.png(seek-shot.sh の出力)
5二重目の独立検証
- [ok] 外部依赖调用点复核(npx playwright / ffmpeg / GSAP 插件 / 字体) — SKILL.md Verify loop 内确有 `npx playwright screenshot --wait-for-timeout=500 "file://$PWD/scribe.html?t=1.2" frame-mid.png`;仓库根 scripts/seek-shot.sh 与 contact-sheet.sh 分别为 npx playwright 与 ffmpeg;draw-on-recipes 第 4 节确有 `import { DrawSVGPlugin } from "gsap/DrawSVGPlugin";` 与 MotionPathPlugin 版本;字体建议在 whiteboard-pipeline 第 3 节。四条均落地,非推测。
- [ok] 「手跟笔尖」机制自洽性 — SKILL.md 的 drawOn 与 reference 的 drawOnWithHand 都把同一个 k 同时用于 `path.style.strokeDashoffset = len * (1 - k)` 与 `path.getPointAtLength(len * k)`,并有 liftTo 在笔画间抬手、unDraw 反向跟随——机制自洽,无「手与线不同源」的写法。
- [ok] 无凭证 / 无业务 API 反查 — 三份文档与仓库脚本中无 API_KEY/token/secret/.env 读取、无 curl/wget、无业务端点调用;GSAP 以裸包名 import(无内嵌 CDN URL),字体建议未附 URL。判橙依据是远程包依赖,不含凭据读取。
- [ok] VO 语速口径跨 skill 一致性 — 本 skill 写「Estimate from VO at ~2.3 words/sec」,同 repo 的 explainer-video 写「~2.3 words/sec (140 wpm)」「scene_seconds = line_words / pace + 0.4」——口径一致,跨 skill 可互操作。
- [ok] 目录资产面清点 — skills/whiteboard-animation/ 下仅 SKILL.md(154 行)、references/draw-on-recipes.md(210 行)与 references/whiteboard-pipeline.md(95 行)、0 字节 README.md;无 scripts/、无手部资产实物、无模板/数据——「纯指令 + 内联代码片段」结论成立(手部 PNG/SVG 由使用者自备,skill 只给标定方法)。
- [ok] 跨引用可解析性 — SKILL.md 两处引用均可解析:`scripts/seek-shot.sh`、`scripts/contact-sheet.sh` 位于仓库根(单装本 skill 目录会悬空,需装整个 repo);`see explainer-video` 指向的 explainer-video 确实存在于本 repo 的 skills/ 下。
- [ok] 功能声明 vs 实际能力 — frontmatter 宣称覆盖 SVG stroke draw-on、跟随笔尖的手、错峰揭示、擦除/擦转场与旁白导出,正文与两份 reference 逐项兑现(含 GSAP 与 Remotion 两条实现路径);未声称能自动生出手部素材或自动描摹——素材转换只给方法不给工具。
6結論
e46a8cf637ab1932…