graphic-gif について
アニメーションGIFを作成するスキルです。通常はCSSアニメーションを使い、明示的な指定があればKlingによる画像から動画への生成にも対応します。短いモーショングラフィックス向けで、HTMLソースとGIFを出力します。
主な機能
- 01CSSアニメーションからGIFを作成
- 02Klingの画像から動画への生成に対応
- 03長さ、フレームレート、スタイル、サイズを設定
- 04フレームを取得してGIFを最適化して出力
活用シーン
- 01SNS向けのアニメーショングラフィック制作
- 02動くテキストやカウンターのGIF化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ varnan-tech/ opendirectory --skill graphic-gifインストール後、Claude Code で/graphic-gifを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdevals/evals.jsonreferences/animation-library.mdstyle-presets.mdscripts/capture-and-encode.mjsexport-gif.sh詳細
graphic-gif
CSS アニメーションまたは AI 画像から動画を生成する API を使用して、ループ再生するアニメーション GIF を生成します。出力:animation.gif。
静止画の PNG または PDF を出力する他のすべての graphic- スキルとは異なり、このスキルはアニメーション .gif を出力します。Playwright と Web Animations API を使って CSS の @keyframes アニメーションをフレームごとにキャプチャする方法(オプション A、デフォルト)、または Kling を使った AI 画像から動画へのパイプライン(オプション B)を使用します。
重要なルール(生成のたびに確認してください)
- デフォルトは css-animated です。 明示的に要求されない限り、
ai-generatedは使用しないでください。 - キャンバスは 800×800px の正方形です。 すべての
clamp()値は 800px を基準に計算してください(1vw = 8px)。 - 自己完結型の HTML ファイルを 1 つだけ使用してください。 すべての CSS は
<style>内に記述します。外部依存関係はフォント CDN の<link>のみです。 - チャットに HTML をそのまま出力しないでください。 ファイルに保存し、概要のみを表示してください。
- フレームのキャプチャには Web Animations API によるシークを使用してください。
setTimeoutループやanimation-delayの工夫は使用しないでください。 - フレーム数を正確にしてください:
Math.floor(duration_seconds * fps)フレームです。t=duration_msのフレームはキャプチャしてはいけません。t=0と重複し、ループ箇所で目に見えるカクつきが発生します。 - プレースホルダーのボックスは使用しないでください。 ビジュアルは CSS だけで生成してください。「画像をここに配置」といった要素は使用しないでください。
- パレットをシンプルにするとファイルサイズが小さくなります。
clean-slate、terminal、electric-burst、brutalistを使用してください。 - ずらして表示するために
animation-delayを使用しないでください。 ずらしは@keyframesのパーセンテージに組み込んでください。フレームシークでタイミングを処理します。 - CSS を書き始める前に、デザインの方向性を決めてください。 トーン、特徴的な要素、動きのスタイル、忘れられないディテールを、コードの最初の行を書く前にすべて決定します。
ステップ 1:情報の確認
必須: prompt(コンテンツの説明と動きの概要)
任意(デフォルト値あり):
| パラメーター | デフォルト | オプション |
|---|---|---|
| animation_type | css-animated | css-animated / ai-generated |
| duration | 3.0 | 秒 |
| fps | 12 | 1 秒あたりのフレーム数 |
| loop | true | true / false |
| style | clean-slate | clean-slate / terminal / electric-burst / brutalist |
| dimensions | 800x800 | WxH(ピクセル) |
| optimization | balanced | quality / balanced / filesize |
prompt がない場合、または動きの説明が不足している場合は、次のとおり正確に尋ねてください:
"GIF に何を表示しますか?コンテンツと動きの両方を説明してください(例:「統計値がカウントアップ:購入者の 73% は、購入前に 3 件以上のコンテンツを読みます。タイプライター効果で、1 文字ずつ表示。スタイル:terminal。3 秒、12fps。」)
主な設定(すべて任意。デフォルト値を表示):
- animation_type: css-animated(デフォルト)または ai-generated
- duration: 3.0 秒
- fps: 12
- loop: true
- style: clean-slate(オプション:clean-slate / terminal / electric-burst / brutalist)
- dimensions: 800x800
- optimization: balanced(オプション:quality / balanced / filesize)"
必須情報がすべてそろっている場合は、ステップ 2 に直接進んでください。
ステップ 2:内部アーキテクチャ(ユーザーには表示されません)
css-animated の場合:
- 次からアニメーションの種類を選択します:
fade-in、slide-in、typewriter、counter、pulse、loop-scroll references/animation-library.mdを読み、選択した種類の HTML/CSS 仕様全体を確認しますreferences/style-presets.mdを読み、選択したスタイルの CSS トークンブロックを読み込みます- フレーム数を計算します:
Math.floor(duration_seconds * fps)— この数値を書き留めます - デザインの方向性を決定します:
| 決定事項 | 導出元 |
|---|---|
| トーン | 対象者に合わせた感情表現(機械的/温かみのある/エネルギッシュ/プロフェッショナル) |
| シグネチャー要素 | 一貫して使用する視覚的な仕掛けを 1 つ(カーソルの点滅、ゴーストナンバー、走査線のオーバーレイ、アクセントボーダー) |
| モーションスタイル | この種類に適したイージング曲線の方針(スプリング/リニア/ステップ/イーズインアウト) |
| 忘れられないディテール | 閲覧者がこの GIF について覚えているであろう 1 つの要素 |
ai-generated の場合:
- ベースとなる静止フレーム HTML を生成します(キャンバス用のポスタースタイルのレイアウト)
- スクリーンショットを使用して PNG としてエクスポートします
- Kling API を呼び出します:動きを説明する
image_urlとpromptを指定してPOST https://api.klingai.com/v1/videos/image2videoを実行します - ジョブの完了をポーリングします
- 動画をダウンロードし、ffmpeg で GIF に変換します:
# Two-pass palette for best color quality ffmpeg -i input.mp4 -vf "fps=12,scale=800:800:flags=lanczos,palettegen=stats_mode=diff" palette.png ffmpeg -i input.mp4 -i palette.png -vf "fps=12,scale=800:800:flags=lanczos,paletteuse=dither=bayer:bayer_scale=5" output.gif
ステップ 3:HTML の生成(css-animated の場合)
生成する前に references/animation-library.md と references/style-presets.md を読みます。
キャンバスの基本設定 — すべての GIF で必須:
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 800px;
height: 800px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
}
.canvas {
width: 800px;
height: 800px;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
アニメーションのルール:
- すべてのアニメーション要素に
animation-fill-mode: forwards(またはboth)を指定します - 種類ごとのタイミング関数:
typewriter→steps(N, end)。N は正確な文字数ですcounter→linearfade-in→cubic-bezier(0.22, 1, 0.36, 1)(イーズアウト)slide-in→cubic-bezier(0.34, 1.56, 0.64, 1)(オーバーシュートするスプリング)pulse→ease-in-outとanimation-iteration-count: infiniteloop-scroll→linearとanimation-iteration-count: infinite
- 1 回だけ再生するアニメーション(fade-in、slide-in、typewriter、counter)では、
animation-iteration-count: 1を指定します。ループは GIF のレベルで行われます animation-delayは使用しません — 時差は@keyframesのパーセンテージに組み込みます
Typewriter の N の計算: スペース、句読点、数字を含むすべての文字を数えます:
- "73% of buyers" = 14 文字 →
steps(14, end) - "Hello, World!" = 13 文字 →
steps(13, end)
Counter CSS の @property(counter の種類で必須):
@property --num {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
.counter {
animation: countUp var(--duration) linear forwards;
counter-reset: num var(--num);
}
.counter::after { content: counter(num); }
@keyframes countUp {
from { --num: 0; }
to { --num: var(--target); }
}
Loop-scroll:コンテンツは必ず複製します:
<div class="ticker-track" style="--item-count: 4;">
[item1][item2][item3][item4][item1][item2][item3][item4]
</div>
translateX(0 → -50%) と linear infinite を使用します。
デザイン品質のルール(ステップ 2 で決めた内容に基づく):
- 名前を付けたシグネチャー要素を CSS/HTML に必ず含めます(説明だけでは不十分です)
- タイポグラフィ:見出しテキストと補足テキストのウェイトのコントラストは最低 2:1 にします(例:700 と 400)
- 背景:ダークスタイルでは純白の
#fffを使わず、プリセットで指定された正確な--bgの値を使用します - ターミナルスタイル:
opacity: 0.03のrepeating-linear-gradientを指定した走査線オーバーレイ::afterを追加します - ブルータリストスタイル:主要な要素に太いボーダー
4px solid #000または4px solid var(--accent)を指定します - 忘れられないディテール:追加の要素が必要な場合は、今すぐ追加します
ステップ 4:セルフ QA(ステップ 5 の前にすべての失敗を修正)
キャンバス:
-
bodyと.canvasが正確に 800×800px(または指定された寸法) -
bodyと.canvasの両方にoverflow: hidden - キャンバスの境界からはみ出す要素がない
アニメーション:
-
animation-delayがどこにもない — 段階的な開始は@keyframesのパーセンテージで設定 - すべてのアニメーションが
t=0で開始(Web Animations API はそこからシークします) - アニメーションのあるすべての要素に
animation-fill-mode: forwardsまたはboth - 1 回限りのアニメーション:
animation-iteration-count: 1 - 無限アニメーション(pulse、loop-scroll):
animation-iteration-count: infinite
種類別のチェック:
- タイプライター:
steps(N, end)の N がテキスト文字列の正確な文字数 - カウンター:
syntax: '<integer>'とinitial-value: 0を指定した@property --numを宣言 - カウンター:
counter-reset: num var(--num)と::after { content: counter(num) } - ループスクロール:HTML 内でコンテンツを正確に 1 回複製
デザイン:
- プレースホルダーのボックスがない
-
references/style-presets.mdのスタイルプリセットトークンを適用 — 単独の 16 進カラーコードを使用しない - ステップ 2 で指定したシグネチャ要素が HTML/CSS に実際に含まれている
- ステップ 2 の印象に残るディテールが実際に実装されている
- 選択したスタイルのフォント用 CDN
<link>がある
ステップ 5:エクスポート
プロンプトからスラッグを決定(ケバブケース、30 文字以下)。出力ディレクトリを作成:
mkdir -p [slug]
HTML を保存:
[slug]/animation.html
ブラウザーで開いて簡単に見た目を確認:
open [slug]/animation.html
エクスポートスクリプトを実行([skill-root] をこのスキルの実際のパスに置き換えます):
bash [skill-root]/scripts/export-gif.sh \
[slug]/animation.html \
[slug]/animation.gif \
--duration [duration] \
--fps [fps] \
[--no-loop if loop=false] \
--optimization [optimization] \
--width [W] \
--height [H]
スクリプトの処理:
- 一時ディレクトリに
gifenc、sharp(またはjimp)、playwrightをインストール - キャッシュされていない場合は Chromium をダウンロード
capture-and-encode.mjsを実行 — アニメーションを一時停止し、各フレームにシークしてスクリーンショットを撮影し、GIF を組み立て- 利用可能な場合は
gifsicleで最適化を実行 - ファイルサイズを報告して結果を開く
エクスポートスクリプトが見つからない場合は、[skill-root]/scripts/export-gif.sh を確認し、scripts/ フォルダーを含めてスキルがインストールされていることを確かめてください。
ステップ 6:出力の概要
エクスポート成功後に表示:
## GIF: [1-line description]
Date: [YYYY-MM-DD] | Style: [style] | Animation: [type] | [duration]s @ [fps]fps
Dimensions: [WxH] | Frames: [N] | Loop: [true/false]
Files
Source: [slug]/animation.html
Output: [slug]/animation.gif
Size: [X] KB
Checklist
- [ ] Preview loops cleanly at start/end point (no stutter)
- [ ] Text legible at intended display size
- [ ] File size appropriate: email <500KB / social <3MB
AI 生成パス(オプション B)
animation_type: ai-generated が明示的に指定されている場合にのみ使用します。
要件:
- 環境変数に Kling API キーを設定:
KLING_API_KEY(無料クレジットは 1 日 66 件、無料プランではクレジットカード不要) - 動画から GIF に変換するため、ローカルに
ffmpegをインストール
ワークフロー:
- プロンプトに一致するベース静止画フレームの HTML を生成(指定された寸法のポスター/グラフィックスタイル)
- 静止画フレームを PNG としてエクスポート:
# Quick screenshot via Playwright node -e " const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: W, height: H } }); await page.goto('file://[slug]/animation.html'); await page.screenshot({ path: '[slug]/base-frame.png' }); await browser.close(); })(); " - Kling の画像から動画へのエンドポイントにアップロード
- ffmpeg の 2 パスパレット方式で結果を GIF に変換
- gifsicle で最適化を適用
Kling が利用できない場合: ユーザーに「AI 生成には Kling API キー(KLING_API_KEY)が必要です。css-animated にフォールバックします。AI 生成を有効にするにはキーを設定してください。」と伝え、css-animated にフォールバックします。
プロンプトのヒント(ユーザーがガイダンスを求めた場合に表示)
「内容だけでなく、動きを説明してください。『統計値が 1 つずつ増える』は『統計値を表示する』より効果的です。」
「ファイルサイズを抑えるため、シンプルにしましょう。アニメーション要素は 1〜3 個、背景は単色にします。」
「ループを意識してください。アニメーションの最後から最初へ、違和感なくつながるようにします。」
「アニメーションの種類を明示してください。
typewriterとcounterは、ソーシャルメディアで特に効果的です。」✅ 良い例:「アニメーション GIF を作成。css-animated、タイプライター効果。テキスト:『73% of B2B buyers read 3+ pieces of content before contacting sales.』文字を 1 文字ずつ順番に入力。スタイル:ターミナル。3 秒、12fps、loop=true。」
❌ 悪い例:「マーケティングのヒントをアニメーション GIF にして」