mcpField
L
lottie-animator

lottie-animator

github.com/obeskayクリエイティブ・メディア23172 回インストール4 週間前に更新
リポジトリ

lottie-animator について

lottie-animatorは、Lottieアニメーションの作成と検証を支援するスキルです。再利用可能なPythonレシピ、Lint、レンダリング、パレット、SVG変換を組み合わせ、JSONの妥当性だけでなく画面上の見た目も確認します。

主な機能

  1. 0122種類のアニメーション生成例
  2. 02LottieのLintとフレーム確認
  3. 03役割別の9色パレット
  4. 04SVGからLottie図形への変換
  5. 05タイミングとイージングの指針

活用シーン

  1. 01既存レシピを使ったローダー作成
  2. 02空白やはみ出しのあるフレームの確認
  3. 03既存Lottieファイルの配色変更
  4. 04SVGアイコンのLottie図形への変換

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/obeskay/lottie-animator-skill --skill lottie-animator

インストール後、Claude Code で/lottie-animatorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
disney-principles.md
examples.md
lottie-gsap-integration.md
lottie-structure.md
lottie-tools-ecosystem.md
motion-taste.md
professional-techniques.md
shape-modifiers.md
svg-to-lottie.md

詳細

Lottie Animator

Lottie は JSON なので、簡単に書ける一方で、誤って書くのも簡単です。特有の厄介な問題があります。壊れた Lottie でも解析は通ります。 polystar の os が欠けている、イージングハンドルの階層が一段深すぎる、ip/op のないレイヤーがある――ファイルは読み込まれ、プレイヤーはエラーを報告せず、キャンバスは空のままです。正しいファイルでも、見栄えが悪いことはあります。直線的、弾みすぎ、詰め込みすぎ、紫色。

そのため、JSON が有効かどうかでアニメーションを判断しないでください。実際に見て判断してください。

以下のパスは、このスキルのディレクトリからの相対パスです。別のプロジェクトから使う場合は、絶対パスで指定してください。レンダラーを使うには、package.json があるリポジトリで一度 npm install を実行する必要があります。

最短ルート:レシピから始める

examples/ には、完成済みでリンティングとレンダリングを済ませたアニメーションを生成する Python ファイルが 22 個あります。白紙から始めるより、最も近いものをベースにするほうが効率的です。タイミング、イージング、構造はすでに適切なので、変更するのはジオメトリと動きの要点だけです。

要望ベースにするもの学べること
成功、完了、保存success-check静止する円盤上でのトリム描画と、控えめな波紋 1 つ
エラー、無効、拒否error-shake主役となる、次第に弱まる揺れ
いいね、お気に入り、リアクションheart-like押す → ポップ → 破裂。遊び心のあるトーンと、その明示
通知、アラートnotification-bell上部の支点を中心とした揺れと、クラッパーの余韻
トグル、スイッチ、設定toggle-switch暗い背景での移動と色のトラック
ロック、プライバシー、アクセスlock-unlock脚を軸に開くシャックルと、状態に応じた色
再生、一時停止、アイコン間の変化play-pause、shape-morph頂点数を合わせたパスのモーフィング
読み込み、待機spinner-arc、typing-dots、panda-loaderトリムの追いかけ、時間差のある波、キャラクターのループ
進行状況、ダウンロード、充電download-progress、battery-charge重なり合うフェーズ、段階的な塗りつぶし
オーディオ、ライブ、録音equalizer基部に固定した、位相をずらしたバー
位置情報、プレゼンスlocation-ping遠近感のある、時間差で広がるリング
天気、アンビエントweather-sunレイピートの光線を、間隔ちょうど 1 つ分だけ回転
送信、共有、移動paper-plane空間タンジェント:弧に沿った動きとバンク
お祝い、報酬confetti-burst弾道を描く弧と、最大 3 色
カード、オンボーディング、リストcard-stack滑らかに連なるカスケード。主役が最後に着地
ロゴの表示logo-draw-on、rocket-launchSVG → Lottie、読み順に沿ったストロークの描画
バウンス、物理挙動bouncing-ball体積を保ったスクワッシュとストレッチ
cp examples/spinner-arc.py build/loader.py
# edit build/loader.py: point its sys.path line at this skill's scripts/ directory,
# then change the geometry and beats to the brief — keep the tokens
python3 build/loader.py --palette night -o build/loader.json

各ジェネレーターの docstring には、その概要(雰囲気、トーン、主役となるプロパティ)が記載されています。変更しても、うまく機能していたアイデアが失われないよう、編集前に読んでください。同じファイルをどの配色でもレンダリングできます。そのため、「ダークモードに合わせる」には書き直すのではなく、--palette night を指定します。

作業の流れ

build  →  lint  →  render  →  LOOK  →  revise

レンダリングを省略しないでください。「JSON は有効です」は、ユーザーにどう見えるかについての主張ではありません。

python3 scripts/lottie_lint.py build/loader.json --strict
node scripts/render.mjs build/loader.json
# Read the filmstrip PNG it prints and actually look at it
node scripts/render.mjs build/loader.json --onion
# the taste pass: Read onion.png and judge the motion, not just the pixels

render.mjs は filmstrip.png を出力します。ファイルが想定する背景(meta.tc。--bg で上書き可能)に、タイムライン全体のフレームをラベル付きで並べ、各フレームのシェイプ数とキャンバスの占有率も表示します。何も描画されない場合(レイヤーの不透明度が 0 になった場合も「何もない」とみなされます)は EMPTY FRAME、アートがフレームの外に出た場合は off canvas、端を越えた場合は clipped と報告します。これでアニメーションが壊れていないことを確認できます。見栄えがよいかどうかは、さらに確認が必要です。--onion は onion.png を出力します。サンプリングしたフレームを古い順に薄く重ねた画像で、残像の間隔がイージングを、その軌跡が弧を表します。references/motion-taste.md の品質確認項目に照らして判断してください。

ツールを利用できない場合(別のリポジトリを使っている、Node がないなど)は、その旨を伝え、代わりに python3 -c "import json; json.load(open('a.json'))" を実行してください。ただし、確認済みであるかのように伝えるのではなく、結果は未検証であることをユーザーに伝えてください。

ジェネレーターの作成

scripts/motion.py はハウススタイルをコードに変換するため、ジェネレーターでハンドル、16 進数の値、必須プロパティを手入力する必要はありません。

import sys; sys.path.insert(0, "<skill>/scripts")
from motion import *

def build(c):                                   # c is a palette, by role
    disc = layer("Disc", group("Disc", ellipse(128), fill(c["accent"])),
                 p=(120, 120),
                 s=track((0, [92, 92], "out"), (22, [100, 100])),
                 o=track((0, 0, "out"), (10, 100)))
    return comp("Disc", 240, 240, [disc], op=90, bg=c["bg"])

if __name__ == "__main__":
    main(build, __file__, palette="paper")      # --palette NAME, -o PATH
  • track((t, value, ease), ...) は最後を除くすべてのキーフレームにハンドルを設定するため、キャンバスがフリーズする不具合は発生しません。delay(track, n) でオフセットしてカスケードを作れます。4 つ目の要素({"to": ..., "ti": ...})を追加すると、位置が弧を描いて移動します。
  • 形状:ellipse、rect、star、path(squircle(w, h, r))、および任意の SVG パスデータを指定できる svg(d, scale, center)。描きやすいグリッド上に描き、center でピボットを図形の中央に移動します。描画:fill、stroke(dash=...)。モディファイア:trim、repeater、round_corners。構造:group(ジオメトリ、描画、次にそのトランスフォーム)、layer(マットには parent="Name"、td/tt)、null、comp。
  • shapes リストとレイヤーリストでは、先頭の項目が最前面に描画されます。

パレット

9 つのパレットで 7 つの役割(bg(背景色。meta.tc に格納)、surface、ink、muted、accent、on_accent、support)を共有し、テストでそれぞれのコントラスト比を確認します。パレットは paper、night、dusk、harbor、citrus、berry、forest、mono、sky です。役割に沿って記述すれば、どのパレットでも使えます。1 つのコンポジションにつきアクセントは 1 色にし、support は面に使用します。背景上の細い線には使わないでください。

  • ブランドカラー: 同じ 7 つの役割を持つ dict を PALETTES に追加し、コントラスト比を確認します。
  • 既存ファイル: LottieFiles、デザイナーなど、入手元を問わず、python3 scripts/recolor.py in.json --list を実行すると、各色の用途とレイヤーがすべて表示されます。次に、各役割について --map "#FF5A5F=#C8522B" -o out.json を実行します。静的およびアニメーションの描画、グラデーションの停止点、ソリッドレイヤーに対応しています。
  • ダークモード: ホストで使われるすべての背景色でレンダリングします。背景と同じ明度の色で描いた線は、コントラストが低いのではなく見えません。レンダリングして初めて確認できます。

実際のジオメトリから始める

ベジェ頂点を手書きしないでください。svg2lottie.py は SVG のパス、矩形、円、楕円、線、多角形、ポリライン、グループ、トランスフォーム、ストローク、線形/放射状グラデーションを Lottie のシェイプレイヤーに変換します。各要素はそれぞれ独立した名前付きレイヤーとなり、要素自体の中心を基準に配置されるため、拡大縮小や回転のピボットが正しく設定されます。

python3 scripts/svg2lottie.py icon.svg -o icon.json --size 512 --current-color "#1E1B18"

アイコンセットは currentColor で描画されます。--current-color を指定しないと、アートワークは黒で出力されます。<text>、<use>、clipPath、mask は警告として報告されます。あらかじめソース SVG でこれらをフラット化してください。出力は意図的に静的なものです。convert() を使って Python から(examples/rocket-launch.py を参照)、または手作業でモーションを追加します。

キーフレームを設定する前に、動きを決めます

キーフレームに触れる前に、次の点に答えてください。30 秒で済み、ほとんどの修正サイクルを防げます。

  1. 感情 — 見る人にどんな気持ちになってほしいですか?(信頼、喜び、緊急性、落ち着き)
  2. 表現のトーン — 指示がない限り、静かで正確にします。オーバーシュートはゼロ、点から大きくなる動きはなし。弾みのある遊び心のある動きは、求められた場合に限ります。
  3. 主役となるプロパティ — 位置、スケール、回転、不透明度、形状のいずれか一つです。ほかのプロパティは、それを補うために振幅を 3 分の 1 未満に抑えます。
  4. タイミング — フィードバックは 60 fps で 6~10 フレーム、登場は 18~30 フレーム、ずらしは 3 フレーム、ループの繰り返し前には少なくとも 12 フレーム保持します。
  5. イージング — 登場には out、移動とループには in-out、退場に限り in を使います。
  6. 配色 — 役割ごとに色を割り当て、アクセントカラーは一色にします。紫のグラデーションや黒地にネオンは使いません。

被写体と競い合う動きはノイズです。削除してください。原則の全容、トークン、センスのチェックについては、references/motion-taste.md を参照してください。

トピック別の詳しい手法: shape-modifiers.md(トリム、リピーター、オフセット、マージ)・ professional-techniques.md(親子付け、リグ、歩行サイクル、プリコンポーズ)・ disney-principles.md・ lottie-gsap-integration.md(スクロールに連動したスクラブ)・ lottie-structure.md・ svg-to-lottie.md・ examples.md・ lottie-tools-ecosystem.md(dotLottie、プレーヤー)

イージング

ハンドルはキーフレームの中に置きます。保持するプロパティの中には置きません。x は 0~1 の範囲内にする必要があります。y は範囲を超えてもよく、それによってオーバーシュートを作れます。そのため、標準設定では y を 0~1 の範囲内に保ちます。 キーフレーム n のハンドルは、n から n+1 までの区間の形状を決めます。誤ったキーフレームにハンドルを置くと、動きの誤った半分にイージングが適用されます。

最後のキーフレームを除くすべてのキーフレームには、動きがリニアな場合も両方のハンドルを設定します。ハンドルのないキーフレームは、lottie-web では「リニア」ではありません。補間中にプレーヤーがエラーを投げ、レンダリング処理が中断され、コンソールには何も表示されないまま、キャンバスが直前のフレームで停止します。ホールドキーフレーム(h: 1)だけが例外です。

トークン(motion.py)用途cubic-bezier
out登場、フィードバック0.23, 1, 0.32, 1
in-out移動とモーフィング、静止状態から静止状態への動き0.77, 0, 0.175, 1
glide大きな面0.32, 0.72, 0, 1
in退場のみ0.55, 0, 1, 0.45
linear一定の回転、一定間隔で移動するオフセット0.333, 0.333, 0.667, 0.667
swing振り子、振動、呼吸0.37, 0, 0.63, 1
standardスピナーの追従、レベルメーター0.4, 0, 0.2, 1
strike打撃後の最初の振り0.61, 1, 0.88, 1
fall / rise重力、正確な t² の動きとその反転0.333, 0, 0.667, 0.333 / 0.333, 0.667, 0.667, 1
playfulオーバーシュート。求められた場合のみ0.34, 1.56, 0.64, 1

ハンドルとして、cubic-bezier(x1, y1, x2, y2) は、動きが始まるキーフレーム上で "o": {"x": [x1], "y": [y1]} および "i": {"x": [x2], "y": [y2]} となります。静止しない動きには linear、swing、standard が適しています。振動に in-out を使うと、折り返すたびに停止し、その間で急に動きます。

空白表示になる不具合

以下の不具合はすべて、かつてこのリポジトリに含まれており、JSON の解析チェックにも合格していました。現在はリンターがすべて検出し、テストで再発を防いでいます。

症状原因
ファイル全体が空白で、コンソールエラーもないイージングハンドルがキーフレーム内ではなくプロパティにある(KF011)
レイヤーが1つ表示されないレイヤーに ip、op、st がなく、再生ヘッドがそのレイヤーに一致しない(LY005)
レイヤーが1つ表示されないシェイプ項目に必須プロパティがなく、プレーヤーがレイヤーを破棄する(SH001)
ジオメトリはあるが、何も見えないグループに塗りまたは線がない(LY015)、あるいは不透明度が全体を通して 0(LY016)
アートの一部がまったく表示されない上に列挙された不透明な兄弟レイヤーの下にグループが描画されている(SH004)
シェイプがサイズ 0 で描画されるジオメトリが gr グループ内ではなく、shapes 内にそのまま置かれている
アートの位置がずれているレイヤーのトランスフォームとグループのトランスフォームの両方に同じオフセットが適用されている
周回ごとに目に見えるジャンプがある最初と最後のキーフレームの値が異なる(KF010)
エラーなしでキャンバスが1フレームに固定される最後以外のキーフレームに o/i ハンドルがないため、lottie-web がレンダリング中に例外をスローし、処理が中断する(KF012)
動きが機械的に感じられる始動・停止する動きにリニアハンドルが使われている(KF007、注記。一定速度の回転や行進するオフセットは対象外)

すべてのレイヤーに ip、op、st が必要です。1つでも欠けると、そのレイヤーはすべてのフレームで非表示になります。

プロパティがないとプレーヤーがレイヤーを破棄する項目 — 動作するファイルから該当プロパティを削除し、結果をレンダリングしてそれぞれ検証済みです。

塗り c,o · 線 c,o,w · グラデーション塗り s,e,g,o · ポリスター p,r,pt,or,os、さらに sy が 1 の場合は ir,is · 楕円 p,s · 長方形 p,s,r · トリム s,e,o · トランスフォーム o。さらに sk がある場合は sa も必要です。

仕様では、トランスフォームの a,p,s,r とグラデーションの t も指定されています。lottie-web はこれらにデフォルト値を補うため、リンターはエラーではなく警告(SH003)として報告します。ただし、ほかのプレーヤーも同じように寛容とは限りません。

仕上げ

完了と伝える前に、以下を確認してください。

  • lottie_lint.py でエラーが報告されないこと(警告も失敗扱いにするには --strict を使用します)。2つの見た目に関する注記 — 点から何かが成長する KF013、イージングがオーバーシュートする KF014 — は、生成された動きによく見られる兆候です。依頼内容で遊び心のある動きが求められていない限り、修正してください。
  • render.mjs で、意図した動きが開始・中間・終了時に確認できること。
  • ループの場合、最初と最後のフレームが一致すること。数値ではなく、フィルムストリップで確認してください。
  • motion-taste.md に記載された見た目の確認を onion.png に対して実施済みであること。間隔にイージングがかかっている、移動軌跡が長く滑らかである、点から何も成長しない、主役が1つ、読み取れる停止時間がある、アクセントカラーが1色であること。
  • 意図的な場合を除き、クリッピングやキャンバス外へのはみ出しがないこと。
  • ホストにダークモードがある場合は、背景ごとに1回レンダリングしてください(ジェネレーターには --palette、完成済みファイルには --bg を使用します)。

確認したことと、確認していないことを報告してください。レンダリングできなかった場合は、動きを確認したかのように述べず、その旨を明確に伝えてください。

コメント