graphic-gif
CSSアニメーションまたはAI画像-動画APIからアニメーションループGIFを生成します。出力: animation.gif
他の graphic- スキルが静的PNGまたはPDFを出力するのとは異なり、このスキルはアニメーション .gif を出力します。PlaywrightとWeb Animations API(オプションA、デフォルト)を介してCSS @keyframes アニメーションをフレームごとにキャプチャするか、Kling(オプションB)を介したAI画像-動画パイプラインを使用します。
重要ルール(各生成前に必読)
- デフォルトはcss-animatedです。 明示的にリクエストがない限り、
ai-generatedは絶対に使用しないでください。 - キャンバスは800×800pxの正方形です。 すべての
clamp()値は800px(1vw = 8px)で計算されます。 - 単一の自己完結型HTML。 すべての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(コンテンツ説明 AND モーションブリーフ)
デフォルト付きオプション:
| パラメータ | デフォルト | オプション |
|---|---|---|
| animation_type | css-animated | css-animated / ai-generated |
| duration | 3.0 | 秒 |
| fps | 12 | フレーム/秒 |
| loop | true | true / false |
| style | clean-slate | clean-slate / terminal / electric-burst / brutalist |
| dimensions | 800x800 | 幅x高さ(ピクセル) |
| optimization | balanced | quality / balanced / filesize |
プロンプトがない場合、またはモーションの説明がない場合は、正確に次のように質問します:
「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を呼び出す:
POST https://api.klingai.com/v1/videos/image2videoにimage_urlとモーションを説明するpromptを含める - ジョブの完了をポーリング
- 動画をダウンロード → ffmpegでGIFに変換:
# 最高の色品質のための2パスパレット 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
- ワンショットアニメーション(fade-in、slide-in、typewriter、counter)の場合:
animation-iteration-count: 1— ループはGIFレベルで行われます animation-delayは使用しない — スタガリングは@keyframesのパーセンテージに組み込みます
タイプライターNの計算: スペース、句読点、数字を含むすべての文字をカウント:
- "73% of buyers" = 14文字 →
steps(14, end) - "Hello, World!" = 13文字 →
steps(13, end)
カウンターCSS @property(カウンタータイプに必須):
@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); }
}
ループスクロール: コンテンツは複製する必要があります:
<!-- 4つのオリジナルアイテム + 4つの複製アイテム -->
<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 vs 400)
- 背景: ダークスタイルの場合、純粋な白
#fffは使用しない — プリセットの正確な--bg値を使用 - terminalスタイルの場合:
opacity: 0.03のrepeating-linear-gradientでスキャンラインオーバーレイ::afterを追加 - brutalistの場合: キー要素に
4px solid #000または4px solid var(--accent)の太い境界線 - 忘れられないディテール: 追加の要素が必要な場合 — 今すぐ追加
ステップ4: セルフQA(ステップ5の前にすべての失敗を修正)
キャンバス:
-
bodyと.canvasが正確に800×800px(または指定された寸法)であること -
overflow: hiddenがbodyと.canvasの両方に設定されていること - キャンバス境界からはみ出している要素がないこと
アニメーション:
- どこにも
animation-delayがないこと — スタガリングは@keyframesのパーセンテージに組み込まれている - すべてのアニメーションが
t=0で開始すること(Web Animations APIはそこからシークする) - すべてのアニメーション要素に
animation-fill-mode: forwardsまたはbothが設定されていること - ワンショットアニメーション:
animation-iteration-count: 1 - 無限アニメーション(pulse、loop-scroll):
animation-iteration-count: infinite
タイプ固有チェック:
- タイプライター:
steps(N, end)のN = テキスト文字列の正確な文字数 - カウンター:
@property --numがsyntax: '<integer>'およびinitial-value: 0で宣言されていること - カウンター:
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行の説明]
日付: [YYYY-MM-DD] | スタイル: [style] | アニメーション: [type] | [duration]秒 @ [fps]fps
寸法: [WxH] | フレーム: [N] | ループ: [true/false]
ファイル
ソース: [slug]/animation.html
出力: [slug]/animation.gif
サイズ: [X] KB
チェックリスト
- [ ] プレビューが開始/終了ポイントでクリーンにループすること(スタッターなし)
- [ ] 意図した表示サイズでテキストが判読可能であること
- [ ] ファイルサイズが適切であること: メール <500KB / ソーシャル <3MB
AI生成パス(オプションB)
animation_type: ai-generated が明示的に指定された場合のみ使用。
要件:
- 環境にKling APIキー:
KLING_API_KEY(1日66無料クレジット、無料ティアにクレジットカード不要) - 動画→GIF変換のために
ffmpegがローカルにインストールされていること
ワークフロー:
- プロンプトに一致するベース静止フレームHTMLを生成(指定寸法のポスター/グラフィックスタイル)
- 静止フレームをPNGとしてエクスポート:
# 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が利用不可の場合: メモ付きでcss-animatedにフォールバック: 「AI生成にはKling APIキー(KLING_API_KEY)が必要です。css-animatedにフォールバックします。AI生成を有効にするにはキーを設定してください。」
プロンプトのヒント(ユーザーがガイダンスを求めたときに表示)
「コンテンツだけでなく、動きを説明してください。'統計を表示' よりも '統計が一つずつカウントアップ' の方が優れています。」
「ファイルサイズのためにシンプルに保ってください。1~3個のアニメーション要素と無地の背景。」
「ループで考えてください。アニメーションは終わりから始まりに目に見えない形で流れるようにする必要があります。」
「アニメーションタイプを明示的に指定してください。
typewriterとcounterはソーシャルに最も効果的です。」✅ 良い例: 「アニメーションGIFを作成、css-animated、タイプライター効果。テキスト: '73% of B2B buyers read 3+ pieces of content before contacting sales.' 各文字が一度に一つずつタイプアウトされます。スタイル: terminal。3秒、12fps、loop=true。」
❌ 悪い例: 「マーケティングのヒントのアニメーションGIFを作成」