procedural-canvas-animation について
procedural-canvas-animationは、プログラムで2D Canvasアニメーションを作るためのスキルです。ジェネレーティブな映像や軽量シミュレーションを扱う制作者向けに、再現可能なフレーム描画、合成、性能、アクセシビリティ、出力検証を説明します。
主な機能
- 01パーティクル、軌跡、天候表現の作成
- 02絶対フレーム番号に基づく描画
- 03決定論的な乱数と状態の再生
- 04透明度とCanvas合成の処理
- 05性能、アクセシビリティ、出力の検証
活用シーン
- 01パーティクルや天候のアニメーション制作
- 02再現可能な動画フレームの描画
- 03透明なアニメーションオーバーレイの作成
- 04アスペクト比やモーション低減版への対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ calesthio/ generative-media-skills --skill procedural-canvas-animationインストール後、Claude Code で/procedural-canvas-animationを入力して読み込まれたか確認します。
同梱ファイルEVAL.md
詳細
プロシージャルキャンバスアニメーション
2D ビットマップキャンバスがプロシージャルな動きを描画するのに適した描画面である場合に、このスキルを使用してください。作成したパーティクル、ベクトル/ノイズフィールド、軌跡、天候、テクスチャ、ジェネレーティブジオメトリ、レンダリングメディア向けの軽量なシミュレーションを扱います。
Three.js のシーングラフ、WebGL/WebGPU シェーダー、D3 のデータセマンティクス、ゲームエンジンのアーキテクチャ、汎用的なフロントエンド向け Canvas チュートリアルは対象外です。
根拠の扱い
- 文書化された事実: WHATWG、ECMAScript、p5.js、W3C、または引用した API ドキュメントに基づく動作です。
- 実運用上のヒューリスティック: 対象のランタイムでテストする実践的な設計または最適化の選択です。
- 実証的な観察: 実際のアニメーション、ブラウザー、フレーム出力、またはエンコード後の配信物で測定した結果です。
事実の検証日は2026-07-12です。Canvas、ブラウザー、p5.js、OffscreenCanvas、エンコードの動作は変わる可能性があります。バージョンを固定し、レンダリング環境を記録してください。
キャンバスの仕様を固定する
次の項目を定義してください。
- バッキングの幅/高さ、CSS/表示サイズ、アスペクト比のバリエーション、fps、フレーム範囲、アルファの要件
- 座標系と、正規化されたシミュレーション空間からの投影
- シード、アルゴリズム、初期化、パラメーター、状態更新の順序
- ステートレス、リプレイ、チェックポイントのいずれかの戦略
- 色空間、合成モード、背景、プリマルチプライドアルファの前提
- ソース画像/フォントと、CORS/オフラインのポリシー
- 対象ランタイム/ブラウザー、ピクセル密度、出力形式、エンコーダー
- 動きを減らしたバリエーション/静止画バリエーションと、フラッシュのポリシー
- パフォーマンス予算と、代表的な負荷の高いフレーム
- すべての素材の出典と権利
ビットマップを理解する
文書化された事実: Canvas には CSS のサイズとは別に固有の解像度があります。デフォルトのビットマップサイズは 300 × 150 です。width または height を設定すると、ビットマップがクリアされ、コンテキストの状態がリセットされます。Canvas 2D の初期合成モードは source-over、globalAlpha の初期値は 1 で、プリマルチプライドアルファが使われます。{alpha:false} を指定して取得したコンテキストは不透明になるため、透明な出力には適しません。
バッキングの寸法を明示的に設定してください。低解像度のバッキングビットマップを CSS で拡大し、高解像度と称してはいけません。固定サイズの動画出力では、正確なピクセル寸法と明示的な密度を選択してください。予測可能な出力にするには、p5.js の pixelDensity(1) が適切なことがよくあります。
サイズ変更は再構築が必要なイベントです。ピクセルやコンテキスト設定が維持されると仮定せず、変換、状態、バッファー、レイアウトを再構築してください。
絶対フレームのインターフェースを使用する
次の形式で設計してください。
renderFrame(frameIndex, variant, accessibilityMode)
合成時間は次のとおりです。
$$ t = \frac{frameIndex}{fps} $$
本番環境の状態管理から requestAnimationFrame() を切り離してください。文書化された事実: rAF は 1 回限りの呼び出しであり、ブラウザーのディスプレイのスケジュールに従います。非表示のコンテキストでは一時停止する場合があり、60 fps を保証しません。p5.js の frameRate() は目標値を要求しますが、オフラインメディアの時間を定義するものではありません。
最終レンダリングの基準として、Date.now()、performance.now()、millis()、deltaTime、変更可能な frameCount を使用しないでください。
決定性の戦略を選択する
ステートレス
(seed, objectId, frameIndex, channel) から各オブジェクトを直接計算します。周期的なフィールド、解析的なパーティクル、プロシージャルな線、任意フレームへのアクセスに最適です。
固定ステップのリプレイ
決定的な初期状態にリセットし、要求されたフレームまで、文書化された順序で正確に $\Delta t = 1/fps$ ずつ進めます。期間が管理可能な場合、雪、群れの動き、セルオートマトンなどの状態を持つシミュレーションに適しています。
チェックポイント
固定フレームごとに決定的な状態を保存し、最も近い過去のチェックポイントからリプレイします。長時間の状態を持つシミュレーションに便利です。チェックポイントのスキーマにバージョンを付け、パラメーターまたはランタイムが変更された場合は使用しないでください。
履歴に依存する永続バッファーの軌跡は、ランダムアクセスできません。履歴をリプレイするか、チェックポイントを保存するか、各フレームに直前の $K$ 個の解析的な位置を描画してください。
乱数シードを明示的に指定する
文書化された事実: ECMAScript の Math.random() は、アルゴリズムが実装依存であり、シードを制御できません。p5.js の randomSeed() と noiseSeed() を使えば、それぞれの系列を再現できますが、p5.js やブラウザーのバージョンをまたいでピクセル単位の同一性が保証されるわけではありません。
シードと乱数生成器の実装を記録してください。任意の時点の値を取得する必要がある場合は、キー付きの乱数値を優先してください。そうすれば、フレーム 200 のレンダリングが、それ以前のフレームで乱数値を何個消費したかに左右されません。
意図するアルゴリズムがフレームをキーにするものではない限り、毎フレーム再シードしないでください。再シードすると、動きが停止したり、相関したりすることがよくあります。
粒子、フィールド、天候、トレイル
各システムについて、次の項目を定義してください。
- 生成領域と寿命。
- 初期位置、速度、形状、色の分布。
- 力・フィールドの方程式と単位。
- 境界での動作:ラップ、反射、消滅、再生成、クランプ。
- 更新順序と衝突ポリシー。
- 正規化されたシミュレーションから各キャンバスへのマッピング。
- トレイル・履歴のポリシー。
- 外れ値と NaN の処理。
シミュレーション状態はピクセルから独立させてください。アスペクト比のバリエーションでは、イベントを共通に保ちながら、フレーミング、数、密度、線幅、フィールドのバイアスを意図的に変更してください。
天候では、視覚的なもっともらしさと物理シミュレーションを区別してください。モデルと入力によって裏付けられない限り、気象学的な正確さを主張しないでください。
合成とアルファ
globalCompositeOperation を意図的に設定し、コンテキストの状態を復元してください。黒、白、チェッカーボードの各背景で、source-over、加算・明るくする効果、マスク、消去をテストしてください。
透過出力の要件:
- コンテキストでアルファが有効であること。
- 意図しない背景塗りつぶしがないこと。
- 出力形式・コーデックがアルファを保持すること。
- 角と端のピクセルを確認すること。
- 受信側のコンポジターで、プリマルチプライドアルファ/ストレートアルファの変換とハローを確認すること。
JPEG はアルファを保持できません。WebCodecs のエンコーダーでアルファがどう扱われるかは、設定とコーデックによって異なります。サポートされていると決めつけず、機能と出力を確認してください。
外部アセットとオリジンの安全性
文書化された事実: 有効な CORS なしでクロスオリジンのメディアを描画すると、キャンバスがオリジンセーフではなくなり、ピクセルの読み取りやシリアル化で SecurityError がスローされることがあります。
可能な場合は、本番用アセットをローカルに固定してください。URL、ライセンス、ハッシュ、CORS ポリシー、失敗時の動作を記録してください。長時間のレンダリング後にキャンバスが汚染されていると判明する事態は避けてください。
p5.js の本番向けパターン
決定論的なオフライン処理では、次のパターンを使います。
function setup() {
pixelDensity(1);
createCanvas(outputWidth, outputHeight, P2D);
noLoop();
initialize(seed);
}
function renderFrame(frame) {
resetOrRestore(frame);
advanceTo(frame, 1 / fps);
drawCurrentState();
}
これはアーキテクチャの例です。advanceTo() では、ステップを必要以上に進めないようにしてください。また、フレーム 0 がステップ実行前の初期状態を表すかどうかを定義してください。
ウィンドウサイズ、入力イベント、実行中のデバイス密度によって最終状態が変わらないようにしてください。resizeCanvas() は出力を消去し、通常は再描画を引き起こすため、宣言したバリエーションを明示的に再構築してください。
パフォーマンス
処理をワーカーに移す前にプロファイルしてください。まず、次の項目を減らしてください。
- アルゴリズムの計算量とペアごとの相互作用。
- パスの再構築とコンテキスト状態の変更の繰り返し。
- 大きなシャドウ・フィルターと過剰な描画。
- ピクセルの読み戻しとピクセル単位のループ。
- フレームループ内でのメモリ割り当て。
- 過剰なオブジェクト数やトレイル履歴。
- 静的レイヤーの冗長な再描画。
文書化された事実: OffscreenCanvas は転送可能で、ワーカー内で実行できますが、ワーカーを使ってもレンダリング全体の時間が短くなるとは限りません。メインスレッドの応答性やパイプラインの分離を改善できる場合があります。ワーカーで利用可能な API を確認し、転送・シリアル化のコストを考慮してください。
ウォーム時とコールド時のフレーム時間、p50・p95、ピークメモリ、出力の読み戻し、終了処理を測定してください。再現性を約束するのは、環境を固定した場合に限ってください。フォント、アンチエイリアス、フィルタリング、浮動小数点演算、色変換は異なることがあります。
アクセシビリティと安全性
意味のある非テキストコンテンツには、同等の代替手段が必要です。色だけに意味を担わせてはならず、意味のあるグラフィックやコントロールの表示には適切なコントラストが必要です。
WCAG 2.2 では、しきい値を下回る場合を除き、1 秒間に 3 回を超える点滅が制限されています。ループ再生中にレンダリングされたループをテストしてください。インタラクティブな画面上で自動的に動くコンテンツが所定の条件に該当する場合は、一時停止・停止・非表示にできるようにする必要があります。
動きの軽減では、動きの表現方法を変える必要があります。たとえば、代表的な静止フレームを使用する、動きをゆっくりにする、移動量を小さくする、パーティクルを減らす、または再生をユーザーが操作できるようにします。FPS だけを下げても、動きの範囲が小さくならず、ぎこちなさが増す場合があります。
装飾用のキャンバスでは、実装の詳細を支援技術から隠し、意味はホスト側で提示してください。キャンバス上のテキストや説明は、キーボードで操作可能なセマンティックなコントロールの代わりにはなりません。
来歴と QA
シード、ジェネレーター、アルゴリズム/ライブラリのバージョン、パラメーター、寸法、fps、フレーム範囲、色空間、密度、ソースアセット/ライセンス/ハッシュ、ランタイム/ブラウザー、および出力ハッシュを記録します。
QA:
- 選択したフレームを直接レンダリングした場合と連続してレンダリングした場合で、宣言した環境/許容誤差の範囲内で一致するか比較します。
- 最初、最後、ループ境界、再生成、衝突、およびアスペクト比の異なるフレームをテストします。
- NaN、Infinity、位置の暴走、上限のないメモリー割り当てを検出します。
- 複数の背景上で透過出力を確認します。
- フルレンダリングの前に CORS/読み取りをテストします。
- ウォームアップ後のフレーム時間の p50/p95 を計測します。
- 最終サイズでの細部、点滅、動きの軽減、および代替手段を確認します。
- 出力のフレーム数、寸法、アルファ、色、およびエンコードを検証します。
例 1:透明な風のリボンのオーバーレイ
これは完全な例であり、必須の方式ではありません。
目的: 8 秒間、30 fps、1920x1080 の透明なオーバーレイに、発光する風の軌跡を 600 本表示します。
方法: シードに 42719 を使用し、正規化された座標と 36 フレームの解析的な軌跡を使います。不変のパーティクルパラメーターは、キー付きジェネレーターから取得します。各位置は、絶対時間の純粋な周期関数として計算します。各フレームでは透明な状態にクリアし、$f-36$ から $f$ までのセグメントを、上限のある経過時間制御のアルファ/幅で描画します。基本のリボンには source-over を使用し、加算合成のハイライトは個別にテストします。
QA: フレーム 0、1、137、239 で、直接レンダリングと連続レンダリングのハッシュを比較します。アルファのヒストグラム/四隅、黒/白/チェッカーボードの背景への合成、p50/p95、点滅テストを確認します。
よくある失敗: 可変の PRNG 消費、{alpha:false}、背景の塗りつぶし、加算合成値のクリッピング、または軌跡を折り返す際のジャンプ。
バリエーション: 9:16 では個数を減らし、流れを縦方向に偏らせます。動きを軽減した出力には、承認済みの静止フレームを使用します。
例 2:再生可能な p5.js の降雪
これは完全な例であり、必須の方式ではありません。
目的: 9:16 と 16:9 の 30 fps で 12 秒間の降雪を生成し、さらに動きを軽減した静止出力も用意します。
方法: pixelDensity(1) と noLoop() を設定し、乱数/ノイズのシードに 8301 を使用します。正規化された状態と固定の $1/30$ ステップを使います。renderFrame(n) ではリセットし、0..n-1 のステップを実行してから描画します。寸法はシミュレーション状態ではなく、投影と構図の余白に影響します。再生成時に値を消費する順序は、決定論的な再生順序に従います。
QA: フレーム 240 を 2 回再生します。投影前の正規化された状態を比較し、NaN/境界外への増大を検出します。トリミング、パフォーマンス、一時停止の挙動、代替手段、および点滅をテストします。
よくある失敗: deltaTime、millis()、frameCount、またはウィンドウ寸法が状態に混入すること、再構築せずにサイズを変更すること、シードの出力がバージョン間で安定していると想定すること。
出典
2026-07-12 に確認済み:
- WHATWG Canvas とアニメーションフレーム:https://html.spec.whatwg.org/multipage/canvas.html および https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animation-frames
- ECMAScript
Math.random:https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.random - draw、frameRate、randomSeed、noiseSeed、pixelDensity、resizeCanvas、noLoop に関する p5.js リファレンス:https://p5js.org/reference/
- MDN の requestAnimationFrame、OffscreenCanvas、Canvas の最適化:https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame 、https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas 、https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas
- WebCodecs:https://www.w3.org/TR/webcodecs/
- WCAG 2.2 の非テキストコンテンツ、点滅、色の使用、非テキストのコントラスト、一時停止・停止・非表示:https://www.w3.org/WAI/WCAG22/Understanding/