Communitygithub.com

ホワイトボードアニメーション

VideoScribe / Doodly スタイル:マーカーハンドがホワイトボード上にイラストや手書き文字をストロークごとに描き、ナレーションで説明します。SVGパスのストローク描画、ハンドトラッキング、段階的表示、消去/ワイプ遷移、ナレーション付きエクスポートに対応します。

ホワイトボードアニメーション とは?

このスキルは、SVGパスアニメーションとマーカーハンドの追跡を組み合わせて、ホワイトボードアニメーション(VideoScribe / Doodly スタイル)を作成するためのものです。コアとなる仕組みは、`stroke-dashoffset` をパス長から0へアニメーションさせることで、パスが「自分自身を描画」する効果です。さらに、`getPointAtLength()` を使用して、描画中のパスの進行位置にマーカーハンドのペン先を正確に追従させ、リアルな手描きの錯覚を生み出します。このスキルは、Claude Code や Cursor などの AI エージェントが、ユーザーの「ホワイトボードアニメーションを作って」「手描きの説明動画を」「VideoScribe スタイルで」といったリクエストに応答するために使用します。単一のHTMLファイルとして出力され、ブラウザで直接開いて再生でき、`?t=N` パラメータで任意の時点をフリーズしてスクリーンショット検証が可能です。ナレーション付きのフレーム確定エクスポートには Remotion への移植もサポートしています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/playlikeboy/videos-skill/tree/HEAD/.claude/skills/whiteboard-animation

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

ホワイトボードアニメーション は何をしますか?

VideoScribe / Doodly の見た目:マーカーハンドがボード上にイラストや手書き文字をストロークごとに描き、ナレーションが説明します。これを、描画するアニメーションSVGパスと、描画先端を追跡するマーカーハンドで構築し、ナレーション順に要素を配置してボードが埋まるようにします。

使用するタイミング

  • 手でアートやテキストをホワイトボードに描く「スクライブ」/ doodle 解説。
  • スケッチやロゴがライブで、線ごとに描かれるアニメーション。
  • 音声に同期して、手書き文字が自身で書き込まれる。
  • 静的なイラストを、ガイド付きのストロークごとのリビールに変換する。

コアメカニズム:SVGストローク描画

stroke-dashoffset をフル長さから0までアニメーションさせることで、パスが「自分自身を描画」します。ダッシュのギャップが縮まり、ストロークが始点から終点に向かって露出します。

const path = document.querySelector("#stroke");
const len  = path.getTotalLength();
path.style.strokeDasharray  = len;       // パス全体と同じ長さの1つのダッシュ
path.style.strokeDashoffset = len;       // 完全に視界外に押し出される = 非表示
path.getBoundingClientRect();            // トランジション前にリフローを強制
path.style.transition       = "stroke-dashoffset 1.2s linear";
path.style.strokeDashoffset = "0";       // 始点→終点を描画

<path> に pathLength="1" を使用して正規化します:すると stroke-dasharray:1; stroke-dashoffset:1 で実際の長さに関係なく任意のパスを描画でき、単一のイージング値(0→1)が描画の進行度になります。linear(または非常に緩やかなイージング)は安定した手の動きとして読み取られます。長いストロークで ease-in-out は避けてください — マーカーが急に動くように見えます。

マーカーハンドが先端を追跡する

錯覚の成否は、ハンドが描画されている正確な点に配置されることに依存します。現在の描画進行度でパスをサンプリングし、毎フレームそこにハンド画像を配置します。ハンドアセットのペン先は、パスの点に合っている必要があります(画像の角ではなくペン先が点に来るようにオフセットします)。

const hand = document.querySelector("#hand");   // <img>/<g>、先端が左上の「ペン先」
const NIB = { x: 6, y: 4 };                      // ハンドアート内のペン先オフセット
function drawOn(path, hand, dur = 1200) {
  const len = path.getTotalLength(), t0 = performance.now();
  path.style.strokeDasharray = len;
  (function frame(now) {
    const k = Math.min(1, (now - t0) / dur);     // 0→1 進行度
    path.style.strokeDashoffset = len * (1 - k); // 始点→先端を露出
    const p = path.getPointAtLength(len * k);    // SVG座標での現在の先端
    hand.setAttribute("transform", `translate(${p.x - NIB.x} ${p.y - NIB.y})`);
    if (k < 1) requestAnimationFrame(frame);
  })(t0);
}

getPointAtLength(len * k) が主力です:strokeDashoffset を駆動している同じ進行度で、パス上の座標を返すので、ペン先が成長するストロークに張り付いたままになります。別々のストロークの間ではハンドを持ち上げます(フェードアウトして、次の開始点にジャンプ)。そうしないと、ハンドが空白のボード上を滑って見えます。

表示順序 — ボードが埋まる

人がシーンを描くように、ナレーション順に要素を配置します:各イラストと各手書きブロックが描画され、ホールドし、次が始まります。1つの描画内でストロークをずらします。各要素が着地した後、ハンドを動かす前に一拍おきます。1つの描画 = VOの1ビートです。2つのものを同時に描かないでください — 目(そして単一のハンド)は1つの先端しか追跡できません。

ステップメカニズム
ストロークを描画stroke-dashoffset len→0、getPointAtLength(len*k) にハンド
マルチストローク描画ストロークをずらす。ハンドは各新しいストロークの開始点にホップする
手書き読み順に描画される文字/単語のストローク、ハンドが追従
ホールド要素完了後、ハンドをボード外で一時停止(0.4~1.0秒)
次の要素ハンドを次の開始点に移動/フェード。その描画を開始
消去 / クリア次のセクションのためにボードをクリアするためにワイプまたは逆描画

アートを描画可能なパスに変換する

描画には、描画順の単一ストロークのオープンパスが必要です — 塗りつぶされた複合シェイプではありません。

  • 線画をオープンストロークとして作成またはトレースします(Illustrator/Inkscape:アウトライン、塗りつぶしではありません)。塗りつぶされたブロブにはアニメーションする「ストローク」がありません。塗りつぶしを中心線のストロークに変換するか、アウトラインパスを描画し、アウトライン完了後に塗りつぶします。
  • 順序が重要です:<path> 要素は、人が描く順序でSVGに現れる必要があります — ドキュメント順でアニメーションさせます。
  • 長く連続した線が最も自然に見えます。実際のペンが持ち上がる場所でのみ分割します。
  • ベタ塗り領域の場合:最初にアウトラインパスを描画し、次にその背後で塗りつぶしをフェード/拡大します(opacity またはクリップリビール)。「後で色を塗った」ように見えます。
  • 手書き:ストローク/手書きフォントを使用し、グリフをパスに変換し、各グリフのパスをストローク順に描画します。または、ごまかします:単語をマスクし、ハンドをマスクエッジに沿わせて左から右へリビールをスイープします。

マーカーハンドアセット

マーカーを持った手のPNG/SVG画像で、ペン先が既知の点にあるもの。ペン先オフセットを一度測定し(上の NIB)、再利用します。一貫性のために、作品全体で1つのハンドアセットを使用します。左手が必要な場合のみミラーリングします(scaleX(-1))。ハンドの下に薄い影を追加して立体感を出します。ハンドが「オフ」のホールド中は影を削除します。

消去 / ワイプ遷移

セクション間でボードをクリアして、ごちゃごちゃしないようにします:

  • ワイプ:塗りつぶされたグループ全体に clip-path(または白い長方形)をアニメーションさせて拭き取り、ハンドはオプションで「消去」。
  • 逆描画:strokeDashoffset を 0→len で実行して描画を戻し、ハンドは後ろ向きに追従。
  • フェード+再描画:古いグループをクロスフェードアウトし、次のグループの描画を開始。

一貫した文法を1つ保ちます(常に左から右にワイプする、など)。そうすることで遷移が意図的に感じられます。

ナレーションへのペーシング

描画時間は、固定タイマーではなく、話されているセリフに追従する必要があります。VOから約2.3語/秒で見積もります。各描画の合計描画時間を、それが示すセリフの長さにおおよそ設定し、さらに短いホールドを追加します。VOが名前を呼ぶラベルは、その単語が話されるちょうどその時に描画が完了するようにします。強調線ではハンドを遅くします。重要な接続ストロークは速くします。完成したボード上にハンドをアイドル状態にしたままナレーションが続かないようにします — ハンドを動かすか、次の要素を開始します。

出力チェックリスト

  • すべてのストロークは単一のオープンパスで描画順になっています。何も完全な形でポップインしません。
  • 各ストローク中、ハンドのペン先が描画先端に正確に位置しています(浮かず、遅れず)。
  • 個別のストローク/要素間ではハンドはきれいに持ち上がります。空白のボード上を滑りません。
  • 要素はナレーション順に、一度に1つずつ描画されます。それぞれ次の前にホールドがあります。
  • 手書きは読み順で描画されます。塗りつぶしはアウトラインの後に表示されます。
  • 消去/ワイプ文法は一貫しています。ボードが過度にごちゃごちゃすることはありません。
  • 描画タイミングは、それが示すVOのセリフに追従します。
  • prefers-reduced-motion:描画アニメーションなしで、完成したボード(すべてのストロークがオフセット0、ハンド非表示)を表示します。

配布と検証(スタンドアロンHTML)

パッケージ化されたヘルパー(scripts/):scripts/seek-shot.sh anim.html 0 1.5 3 で ?t=N ハーネスをフリーズし、各瞬間をスクリーンショットします。scripts/contact-sheet.sh sheet.png frame-*.png でそれらをタイル状に並べ、一目でレビューできます。scripts/README.md を参照。

自己完結型のホワイトボードシーン(描画イラスト、手書き、短いスクライブビート)の場合、成果物はブラウザで直接開く1つのHTMLファイルです — ビルドステップやレンダリングパイプラインは不要です。Webモーションには単一ファイルが適切なレベルです。1つのファイルで済むのにバンドラーに手を出さないでください。(焼き込みVO付きのフルナレーションスクライブビデオの場合は、Remotionコンポジションとして構築し、remotion still で検証してください — explainer-video を参照。)

出力契約:

  • 1つの .html ファイル:インラインSVG(描画順のパス、pathLength="1" または実測長)、インラインまたはデータURIのハンドアセット、1つのインライン <script> 内の描画ドライバー。
  • すべての描画は1つのマスタータイムライン上(GSAP tl、または1つのrAFクロック)。これにより、シーケンス全体が単一の再生ヘッドを持ち、シーク可能になります — strokeDashoffset とハンド位置の両方が同じ進行値で駆動されます。
  • 以下のシークハーネスを含め、任意の瞬間をスクリーンショット用にフリーズできるようにします。t でフリーズすると、パスのどの程度が描画されたかが正確にわかります — 検証はこれに依存します。

シークハーネス — スクリーンショット用に正確な瞬間をフリーズ。 ?t=N はマスタータイムラインを N 秒にシークして一時停止するため、スクリーンショットは描画途中の静止した決定論的なフレームをキャプチャします。

<script>
  // ... マスタータイムラインを `tl` として構築(drawOn呼び出しを配置) ...
  const t = new URLSearchParams(location.search).get("t");
  if (t !== null) { tl.pause(); tl.seek(parseFloat(t)); }  // t秒でフリーズ
  // ?t なし → 通常再生
  window.__ready = true;            // ヘッドレス待機用の準備信号
  console.log("duration", tl.duration());
</script>

検証ループ — レンダリング → フリーズ → スクリーンショット → チェック:

  1. タイムライン上の瞬間(開始、描画途中のフレーム、終了)でファイルを開く:…/scribe.html?t=0、?t=<dur/2>、?t=<dur>。終了時間はコンソールの tl.duration() から読み取ります。少なくとも1つの t をストロークの途中で選びます — ここでハンドオンチップの錯覚が証明または破綻します。
  2. 各フリーズフレームをヘッドレスでスクリーンショット:
    npx playwright screenshot --wait-for-timeout=500 "file://$PWD/scribe.html?t=1.2" frame-mid.png
    
  3. 各静止画を検査 — 忠実度を確認:ストローク途中の t で、ハンドのペン先が描画部分の最先端に正確に位置している(先行していない、遅れていない、浮いていない)。パスは先端までのみ描画されている。?t=<dur> ですべてのストロークがきれいに完了し、ギャップ、オーバーシュート、残ったダッシュがない。アーティファクトを確認:ストローク間でハンドが空白のボード上を滑っている、ペン先オフセットが間違っている(先端が線から浮いている)、ストロークが順序通りに描画されていない、アウトラインの前に塗りつぶしが表示されている、クリップ/キャンバス外の描画、フォント読み込み前のFOUC。
  4. 繰り返す:NIB、ストローク順、時間を調整し、各フリーズフレームが手描き途中のように見えるまで再スクリーンショット。

終了前に:

  1. ブラウザでスタンドアロンで開く — コンソールエラー、CDN/アセットの欠落なし。
  2. 1つのマスタータイムライン。?t=N で正しくフリーズし、strokeDashoffset とハンド位置が1つの進行値を共有している。
  3. 開始/ストローク途中/終了でスクリーンショット — ハンドのペン先が全体を通して先端にあり、ストロークは終了できれいに完了、描画順が正しい。
  4. ストローク間でハンドが持ち上がる。空白のボード上を滑らない。
  5. prefers-reduced-motion は、描画アニメーションなしで完成したボード(すべてのストローク描画済み、ハンド非表示)を表示する。

ナレーション付きのフレーム確定エクスポートについては、同じ描画ロジック(useCurrentFrame()/fps から strokeDashoffset とハンド変換を駆動)をRemotionコンポジションに移植し、MP4/GIFにレンダリングします — レンダリングスチル→エンコードループについては explainer-video スキルを参照。

リファレンスファイル

  • references/draw-on-recipes.md — 実行可能な描画メカニズム:getTotalLength/getPointAtLength ハンド追跡パス、GSAP DrawSVGPlugin および MotionPathPlugin のバリアント、マルチストロークのずらし、グリフ単位の手書き、塗りつぶし後のアウトライン、消去/ワイプと逆描画トランジション、およびRemotionフレーム駆動ポート。
  • references/whiteboard-pipeline.md — アートを描画可能な単一ストロークSVGに変換する、描画順の作成、手書き/ストロークフォント、マーカーハンドアセットとペン先キャリブレーション、描画時間をVOのセリフに合わせる、ストーリーボードからボードへの構築シーケンス。

Individual skills in this repo

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

animated-infographic

This skill should be used when the user asks to "make an animated infographic", "create an infographic video", "build an infographic animation", "animate an explainer infographic", "do a sequenced reveal of icons and stats", "animate icons with key numbers and connectors", or "lay out a designed infographic that animates in sequence". Covers infographic layout & visual hierarchy, staggered element reveals, animating icons/pictograms, key-number counters, connectors/flow, and section pacing. For heavy charting (bar chart race, charts from a CSV) use the chart-animation skill instead.

brand-motion-guidelines

This skill should be used when the user asks to "write motion guidelines", "create a brand motion system", "define easing and timing tokens", "document our animation principles", "build a motion language like Slack/IBM/Klarna", "set up entrance/exit/transition rules", or "add a reduced-motion / accessibility section". It outputs a fill-in-ready brand motion guidelines document.

explainer-video

This skill should be used when the user asks to "make an explainer video", "turn this into a short explainer", "write a script and storyboard for a product video", "produce a how-it-works/onboarding video", "sync narration and captions", or "build a 30–90s animated explainer". Covers script→storyboard→scene build→narration/caption sync→edit→polish.

presentation-video

This skill should be used when the user asks to "make an animated presentation", "turn a pitch deck into a video", "convert slides/a deck to video", "make a presentation video", "build a deck video", "narrate a slide deck as a video", or "auto-advance slides synced to a voiceover". Covers rebuilding slides as motion graphics with staggered build reveals, slide-to-slide transitions, and timing locked to per-slide narration.

product-demo-video

This skill should be used when the user asks to "make a product demo video", "create an app demo video", "build a feature announcement video", "do a SaaS demo", "make a UI walkthrough video", "animate product screenshots into a demo", "add an animated cursor/click to a screenshot", or "zoom into part of a UI". Covers turning static screenshots/designs (not screen recordings) into a clean animated demo: device/browser frames, animated cursor + click ripple, zoom/pan to focal UI, callout annotations, step pacing, screen-to-screen transitions, and feature captions.

shot-composition

This skill should be used when the user asks to "compose a frame", "set up a grid", "plan shot composition", "place the focal point", "decide where elements enter and exit", "add a parallax/camera move", "adapt a layout for 16:9 / 9:16 / 1:1", or "keep content inside safe areas". Covers grids, safe areas, focal hierarchy, and 2D/3D camera framing.

関連スキル