creator-plugin-development について
LottieFiles Creator のプラグイン開発者向けスキルです。シーンを操作するサンドボックスと React UI の分離構成を説明し、API やメッセージ通信の実践方法を扱います。
主な機能
- 01サンドボックスと UI の構成
- 02シーン、レイヤー、シェイプ操作
- 03キーフレームアニメーションの手法
- 04アセットのインポート方法
- 05型付きメッセージ通信
- 06開発・検証コマンド
活用シーン
- 01Creator プラグインのひな形作成
- 02シーン要素の作成やアニメーション化
- 03SVG、画像、Lottie アセットの読み込み
- 04UI とプラグイン間の通信障害の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lottiefiles/ creator-plugin-skills --skill creator-plugin-developmentインストール後、Claude Code で/creator-plugin-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/architecture-and-communication.mdimporting-assets.mdnetwork-and-libraries.mdscene-graph-and-nodes.mdshapes-styling-animation.mdstorage-and-events.md詳細
Creator プラグインの開発
Creator プラグインは、アニメーション作成アプリケーションの LottieFiles Creator を拡張します。2 部構成のサンドボックスアーキテクチャを採用しています。
- プラグインサンドボックス(
plugin/plugin.ts)—creatorグローバル API にアクセスできる分離環境で実行されます。シーン、レイヤー、シェイプ、キーフレームを操作できます。ネットワークリクエストは実行できません。 - UI(
src/)— iframe 内でレンダリングされる標準的な React アプリケーションです。fetchでネットワークリクエストを実行できます。creatorAPI にはアクセスできません。
2 つの部分は、メッセージの送受信のみで通信します。
プロジェクト構成
my-plugin/
├── plugin/
│ ├── manifest.json # Plugin metadata (id, name, apiVersion, entry, ui)
│ ├── plugin.ts # Sandbox code — has `creator` API access
│ └── [helpers].ts # Optional helper modules
├── src/
│ ├── main.tsx # React DOM entry point
│ ├── app.tsx # Main UI component
│ └── components/ # React components
├── vite.config.ts # Uses @lottiefiles/vite-plugin-creator
├── tsconfig.json # Root config with references
├── tsconfig.plugin.json # Plugin sandbox TypeScript config (no DOM)
├── tsconfig.app.json # UI TypeScript config (DOM + JSX)
├── index.html # Vite app template
└── package.json
tsconfig.plugin.json はサンドボックスコードをコンパイルします(DOM ライブラリは含まれません)。tsconfig.app.json は UI コードをコンパイルします(DOM と JSX を含みます)。
プラグインマニフェスト(plugin/manifest.json)では、プラグインの識別情報とエントリーポイントを定義します。
{
"id": "unique-uuid-v4",
"name": "My Plugin",
"apiVersion": "1",
"entry": "plugin.js",
"ui": "ui.html"
}
開発コマンド
npm create @lottiefiles/creator-plugin@latest my-plugin # Scaffold a new plugin
# From the plugin directory (e.g., plugins/my-plugin/):
npm run dev # Start dev server with HTTPS hot-reload
npm run build # TypeScript check + Vite production build
npm exec tsc -- -b # Type check (run before completing any task)
Creator で読み込むには、プラグイン > 開発 > 新しいプラグインを選択し、npm run dev で表示された localhost URL を入力します。
通信パターン(重要)
これは最もよくあるバグの原因です。メッセージのラップ方法は非対称です。
UI からプラグインへ
// In UI code (src/app.tsx) — MUST wrap in pluginMessage object
parent.postMessage(
{ pluginMessage: { type: 'create-shape', color: '#ff0000' } },
'*'
);
プラグインがメッセージを受信する
// In plugin sandbox (plugin/plugin.ts) — messages arrive unwrapped
creator.ui.onMessage((msg) => {
if (msg.type === 'create-shape') {
// Use creator API here
}
});
プラグインから UI へ
// In plugin sandbox — no wrapping needed
creator.ui.postMessage({ type: 'shape-created', layerId: layer.id });
UI がメッセージを受信する
// In UI code — messages arrive wrapped in pluginMessage
window.addEventListener('message', (event) => {
const message = event.data.pluginMessage;
if (message?.type === 'shape-created') {
// Handle response
}
});
型安全なメッセージ
コンパイル時に不一致を検出できるよう、共有メッセージ型を定義します。
// shared/types.ts
export type PluginMessage =
| { type: 'create-shape'; color: string }
| { type: 'import-svg'; content: string }
| { type: 'delete-selection' };
リクエストとレスポンスを追跡するには、messageId フィールドを含めます。
主な API パターン
プラグインを初期化する
creator.ui.show({ width: 300, height: 500 });
シーンへのアクセス
const scene = creator.activeScene;
scene.size; // { width, height }
scene.duration; // seconds
scene.framerate; // FPS
scene.layers; // ReadonlyArray<Layer>
シェイプの作成
const layer = creator.activeScene.createShapeLayer();
const rect = layer.createRectangle({ size: { width: 200, height: 150 } });
layer.createFill({ type: 'SOLID', color: { r: 66, g: 133, b: 244 } });
アセットのインポート
// From URL
const anim = await scene.import({ type: 'LOTTIE', url: 'https://...' });
const img = await scene.import({ type: 'IMAGE', url: 'https://...' });
const svg = await scene.import({ type: 'SVG', url: 'https://...' });
// From content string
const svgLayer = await scene.import({ type: 'SVG', content: svgString });
// Audio, from a URL or base64 content
const audio = await scene.import({ type: 'AUDIO', content: base64Audio });
LOTTIE と SVG のインポートでは SceneLayer が返されます。IMAGE のインポートでは ImageLayer が返されます。AUDIO のインポートでは AudioLayer が返されます。インポートに失敗すると拒否されるため、scene.import() は try/catch で囲んでください。
プロパティのアニメーション
layer.position.addKeyframes([
{ frame: 0, value: { x: 100, y: 100 } },
{ frame: 60, value: { x: 400, y: 100 } },
]);
// With easing
const easeInOut = { type: 'CUBIC_BEZIER', x1: 0.42, y1: 0, x2: 0.58, y2: 1 };
layer.position.addKeyframes([
{ frame: 0, value: { x: 50, y: 100 }, easing: easeInOut },
{ frame: 60, value: { x: 350, y: 100 } },
]);
選択
const selectedNodes = creator.selection.nodes;
creator.on('selection:nodes', (nodes) => {
creator.ui.postMessage({ type: 'selection-changed', count: nodes.length });
});
ノード型の確認
操作の前に必ずノード型を確認し、サポートしていない型はスキップしてください。scene.layers、creator.selection.nodes、selection:nodes、shapes、creator.assets は、インストール済みの API 型より新しい型を含め、プラグインが認識しない型を返すことがあります。references/scene-graph-and-nodes.md の「Unknown Node Types」を参照してください。
const layers = creator.selection.nodes;
layers.forEach((node) => {
if (node.type === 'SHAPE_LAYER') {
// Shape layer operations (has .shapes, .fills, .strokes, .trimPaths)
} else if (node.type === 'IMAGE_LAYER') {
// Image layer operations (has .image)
} else if (node.type === 'SCENE_LAYER') {
// Scene layer operations (has .scene, .break())
} else if (node.type === 'TEXT_LAYER') {
// Text layer operations (has .text, .fontFamily, .fontStyle, .fontSize,
// .alignment, .fill/.createFill, .stroke/.createStroke)
} else if (node.type === 'NULL_LAYER') {
// Null layer operations (transform only, has .layers)
} else if (node.type === 'AUDIO_LAYER') {
// Audio layer operations (has .audio, .muted, .volume; no transform)
}
// Any other type: skip it
});
オーディオレイヤーにはトランスフォームがありません。scene.layers または選択範囲から取得したレイヤーの position、opacity、その他のトランスフォームメンバーを読み取る前に、その型を確認するか、creator.utils.isTransformableLayer(layer) を使用してください。references/scene-graph-and-nodes.md を参照してください。
ネットワークリクエスト
プラグインサンドボックスでは fetch リクエストを実行できません。次のパターンを使用してください。
- UI が外部 API からデータを取得する
- UI が
parent.postMessage({ pluginMessage: ... }, '*')でプラグインにデータを送信する - プラグインがデータを処理してシーンに適用する
完全な例については、references/network-and-libraries.md を参照してください。
よくある落とし穴
pluginMessageラッパーがない — UI からプラグインへのメッセージは、必ず{ pluginMessage: { ... } }でラップする必要があります。プラグインから UI へのメッセージはラップ不要です。- プラグインのサンドボックスから取得する — ネットワークリクエストは UI コードからのみ実行できます。
fetchの呼び出しはsrc/に移してください。 localStorage/sessionStorageを使用する — サンドボックス化された iframe では、ブラウザーのストレージ API がブロックされます。代わりにプラグインコードからcreator.clientStorageを使用してください。- ノードの種類を確認しない — 種類固有のプロパティにアクセスする前に、必ず
node.typeを確認してください。 - アニメーション中のプロパティに
staticValueを設定する — キーフレームがあるときにstaticValueを設定しても、アニメーションには反映されません。先にキーフレームをクリアするか、キーフレームの値を直接変更してください。 - 図形が表示されない — 図形を表示するには、塗りつぶしかストロークが必要です。
createRectangle()の後にcreateFill()を呼び出してください。 - スケール値はパーセンテージ —
100はスケール 100%(1.0ではありません)です。通常のサイズには{ x: 100, y: 100 }を使用してください。 - 不透明度は 0~100 — 0~1 ではありません。完全に不透明にするには
100を使用してください。 - 色の値は 0~255 — RGB チャンネルには、範囲
{ r: 0-255, g: 0-255, b: 0-255 }の値を使用します。 creator.ui.show()を早い段階で呼び出さない —plugin.tsの先頭で、メッセージハンドラーを設定する前に呼び出してください。- UI の準備が整う前にメッセージを送信する —
creator.ui.show()の直後にcreator.ui.postMessage()を呼び出すと、iframe の読み込みが完了していないため、メッセージが破棄されます。「ui-ready」ハンドシェイクを使用してください。UI のマウント時に{ type: 'ui-ready' }を送信し、プラグインはそのメッセージを受信してからデータを送信します。 - すべてのレイヤーにトランスフォームがあると想定する — オーディオレイヤーには
visible、position、scale、rotation、opacityがありません。scene.layersを走査してこれらのメンバーを読み取るコードはコンパイルに失敗し、オーディオを含むプロジェクトでは実行時にもエラーになります。先に種類でフィルタリングし、処理しない種類はスキップしてください。
検証チェックリスト
タスクを完了とする前に、次を確認してください。
-
npm exec tsc -- -bを実行し、すべての型エラーを修正する - メッセージの流れをテストする:UI が送信 > プラグインが受信 > プラグインが応答 > UI が受信
- ネットワークリクエストがプラグインのサンドボックスではなく、UI コードから実行されていることを確認する
- 双方向の
pluginMessageラッパーが正しいことを確認する
リファレンスガイド
詳しい情報は、必要に応じて次のリファレンスファイルを参照してください。
| リファレンス | 参照するタイミング |
|---|---|
references/architecture-and-communication.md | アーキテクチャ、メッセージパッシングの完全な例、UI API の詳細を確認するとき |
references/scene-graph-and-nodes.md | シーン階層、ノードの種類、走査パターンを確認するとき |
references/shapes-styling-animation.md | 図形の作成、塗りつぶし/ストローク/グラデーション、キーフレーム、イージングを確認するとき |
references/importing-assets.md | LOTTIE/SVG/IMAGE/AUDIO のインポート形式とパターンを確認するとき |
references/storage-and-events.md | clientStorage、ノードデータ、選択イベント、タイムライン API を確認するとき |
references/network-and-libraries.md | UI から取得するパターン、npm パッケージの使用方法を確認するとき |