Communityコーディング&開発github.com

iart-ai/ecommerce-video-skills

スクリーンショット、価格、画像フォルダから直接、製品デモ、セールプロモーション、フォトスライドショーなどのEC/製品動画を生成します。

ecommerce-video-skills とは?

このスキルは、静的な製品スクリーンショットやデザインを、プロフェッショナルなアニメーション製品デモ動画に変換するためのものです。画面上の動きをリアルタイム録画するのではなく、コードベースでカーソルの移動、クリック効果、ズームイン、画面遷移、キャプションアノテーションを正確に制御します。主にRemotionフレームワークを使用し、すべてのアニメーション値をフレーム番号の純関数として計算するため、再現性が高く、スクリーンショットの差し替えも容易です。Claude Code、Cursor、CodexなどのAIエージェントプラットフォーム上で動作し、開発者が製品デモ、機能紹介、UIウォークスルー動画を効率的に作成するのに役立ちます。入出力仕様が明確に定義されており、フレームごとのスチル画像確認からMP4/GIFエンコードまでの検証フローを備えています。

対応~Claude Code~Codex CLI✓Cursor
npx skills add iart-ai/ecommerce-video-skills

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

製品デモ動画

静的な製品スクリーンショットやデザインを、洗練されたアニメーションデモに変換します。画面録画は不要、ジッターのある実際のカーソルも、UIのバージョンずれもありません。各画面をフレームに収め、合成カーソルを正確なピクセルまで滑らかに移動させ、クリックリップルを発生させ、重要な部分にズームインして機能をキャプションします。入力が静的でモーションがコードであるため、すべての値は決定論的であり、スクリーンショットが変更されても同一に再レンダリングされます。

使用するタイミング

  • アプリ/SaaSデモ、機能発表、オンボーディングウォークスルー(15~90秒)。
  • スクリーンショットやデザインしかないUIのクリックパスを表示する場合。
  • 情報量の多いダッシュボードの1つの焦点領域を強調する場合(領域へのズーム+コールアウト)。

スクリーンショットが画面録画に勝る理由

画面録画スクリーンショット駆動(このスキル)
実際のカーソルがドリフト、オーバーシュート、ジッターするカーソルがイージングされたパスで正確なターゲットに移動
1つのステップを修正するために全体を録画し直す1つのPNGを交換し、同じコードを再レンダリング
撮影中にUIが変更され、マウスが迷う各画面はクリーンで最終状態のアセット
ピクセル化せずにズームするのが難しいスクリーンショットを2倍(DPR 2)でエクスポート → 鮮明なズーム

入力はディスプレイサイズの2倍(Retina / deviceScaleFactor: 2)でキャプチャし、2倍ズームでも鮮明さを保ちます。Playwrightキャプチャスクリプトについては references/screenshot-demo.md を参照してください。

デモのループ

すべてのデモは同じビートを、機能ごとに繰り返します。読み取るのに十分な時間保持し、意図を持って移動し、クリックを着地させ、結果を表示します。

ビート所要時間役割
画面に落ち着く0.5~1秒ビューアが何も動く前に方向を定められるようにする
カーソルがターゲットに移動0.4~0.8秒イージングされた移動(イーズインアウト)、線形ではない
クリックリップル+状態変化0.2~0.3秒触覚フィードバック。画面は同じフレームで反応
焦点領域にズーム1~2秒でイン、2~4秒ホールド2倍が最適。十分なディテール、コンテキストを維持
機能をキャプションズーム中にホールド1つの利点フレーズ、例:「ワンクリックエクスポート」

カメラまたはカーソルのいずれかを動かし、両方を同時に動かすことは避けてください。2つの同時モーションは注意を分割します。

スクリーンショットをフレームに入れる

生のスクリーンショットはバグレポートのように見えますが、フレームに入ったものは製品のように見えます。すべての画面をブラウザまたはデバイスのクロムでラップし、ブランドの背景に配置します。

// ブラウザフレーム — スクリーンショットを入れると、信頼できるウィンドウになる
const BrowserFrame = ({ url, children }) => (
  <div style={{ borderRadius: 12, overflow: "hidden", background: "#1e1e22",
                boxShadow: "0 40px 80px rgba(0,0,0,.35)" }}>
    <div style={{ height: 40, display: "flex", alignItems: "center", gap: 8, padding: "0 14px" }}>
      {["#ff5f57", "#febc2e", "#28c840"].map((c) => (
        <span key={c} style={{ width: 12, height: 12, borderRadius: "50%", background: c }} />
      ))}
      <div style={{ marginLeft: 12, flex: 1, height: 24, borderRadius: 6, background: "#2b2b30",
                    color: "#9aa", fontSize: 13, display: "flex", alignItems: "center", padding: "0 10px" }}>
        {url}
      </div>
    </div>
    <div style={{ background: "#fff" }}>{children}</div>
  </div>
);

アドレスバーに実際のURLを入れ(信頼性)、柔らかいシャドウとグラデーションの背景を追加します。モバイルの場合は、ノッチと角丸を備えた電話フレームに切り替えます。フレームスタイルを1つのテーマオブジェクトにまとめ、すべての画面が一致するようにします。

アニメーションカーソル+クリックリップル(コアムーブ)

位置は現在のフレームから駆動し、CSSトランジションやウォールクロックからは決して駆動しません。ビデオレンダラーはすべてのフレームをフレーム番号の純関数にする必要があります。そうしないと、カーソルが同期せずちらつきます。

import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";

// `startFrame` から `startFrame+dur` の間、`from` から `to` へのイージングされた移動
const useCursor = (from, to, startFrame, dur) => {
  const frame = useCurrentFrame();
  const t = interpolate(frame, [startFrame, startFrame + dur], [0, 1],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => x * x * (3 - 2 * x) }); // スムーズステップ
  return { x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t };
};

export const Cursor = ({ from, to, startFrame, dur, clickAt }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const { x, y } = useCursor(from, to, startFrame, dur);

  // リップルはクリックフレームで一度だけ拡大
  const since = frame - clickAt;
  const showRipple = since >= 0 && since < 18;
  const r = spring({ frame: since, fps, config: { damping: 18 }, durationInFrames: 18 });

  return (
    <>
      {showRipple && (
        <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)",
          width: 12 + r * 60, height: 12 + r * 60, borderRadius: "50%",
          border: "2px solid rgba(80,140,255,.9)", opacity: 1 - r }} />
      )}
      <svg width="28" height="28" viewBox="0 0 28 28"
           style={{ position: "absolute", left: x, top: y, filter: "drop-shadow(0 2px 3px rgba(0,0,0,.4))" }}>
        <path d="M3 2 L3 21 L9 15 L13 24 L16 23 L12 14 L20 14 Z" fill="#fff" stroke="#222" strokeWidth="1.4" />
      </svg>
    </>
  );
};

カーソルはスムーズステップを使用するため、静止状態から加速し、ターゲットに向かって減速します(線形カーソルはロボットのように見えます)。リップルと画面の状態変化を同じ clickAt フレームで発生させ、原因と結果が一致するようにします。複数の画面にわたる複数のクリックを配線する完全な構成については、references/screenshot-demo.md を参照してください。

領域へのズーム(UI用ケンバーンズ効果)

焦点要素にズームインするには、画面を拡大し、transform-origin をその要素の中央に設定します。これにより、フレーム中央ではなく、その要素に収束するようにズームします。

const ZoomToRegion = ({ target, scale = 2, startFrame, dur, children }) => {
  const frame = useCurrentFrame();
  const s = interpolate(frame, [startFrame, startFrame + dur], [1, scale],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => 1 - Math.pow(1 - x, 3) }); // easeOutCubic
  return (
    <div style={{ transform: `scale(${s})`, transformOrigin: `${target.x}px ${target.y}px`,
                  willChange: "transform" }}>
      {children}
    </div>
  );
};

ズームは約2倍に制限します(3倍を超えるとコンテキストを失い、方向感覚を失わせます)。ズーム状態を2~4秒保持します(詳細を読むのに十分な時間)。その後、次の画面に移動する前にイーズアウトして戻します。ズームはコールアウトと組み合わせ、単独では使用しないでください。

コールアウトアノテーションと機能キャプション

変化点に注釈を付け、それを消去します。コールアウトは、ラベルと、焦点要素を指すコネクタ(矢印、円、下線)で構成されます。

  • ハイライト:要素を柔らかいリングまたは薄暗い周囲で囲みます(box-shadow: 0 0 0 9999px rgba(0,0,0,.45) でスポットライトの穴を開けます)。
  • キャプション:ビートごとに1つの利点を説明します。短い名詞句(「リアルタイム分析」)で、文章にしないでください。ズーム時に表示され、次のステップの前に消えます。
  • キャプションは画面下部3分の1かつタイトルセーフエリア内に配置し、9:16へのトリミングに耐えられるようにします。

スポットライトマスク、矢印コネクタ、タイプ付きキャプショントラックについては、references/annotation-and-transitions.md を参照してください。

画面間トランジション

ステップ間では、一貫した1つの言語で画面を移動します。1つを選択し、それを維持します。

トランジション感触用途
プッシュ / スライド「次のステップ」への前方向きな動きリニアなウォークスルー
クロスズーム勢い、アプリ風詳細ビューへのジャンプ
クロスフェード落ち着いた、ニュートラルコンテキストの切り替え(設定 → ダッシュボード)
共有要素でのマッチカットシームレス同じカードが画面間で持続

遷移元の画面は、そのクリックが解決されるまで保持し、その後トランジションします。動きの途中でカットすることは避けてください。references/annotation-and-transitions.md を参照してください。

出力チェックリスト

  • 入力は2倍(DPR 2)でキャプチャ。ズームは2倍で鮮明に保たれます。
  • すべてのカーソル/ズーム値は useCurrentFrame() の純関数です。アニメーション状態にCSSトランジションは使用しません。
  • カーソルはイージングされたパス(スムーズステップ)で移動。リップルと状態変化は同じクリックフレームで発生します。
  • 各画面はフレーム(ブラウザ/デバイス)に入れられ、実際のURLと一貫したテーマを持ちます。
  • 一度に1つのモーション(カメラまたはカーソル)。ズーム ≤ 2倍、2~4秒保持。
  • ビートごとに1つの利点キャプションをタイトルセーフな下部3分の1に配置。トランジションは1つの一貫した言語を使用します。

納品と検証(レンダリングされた静止画 → MP4)

パッケージ化されたヘルパー(scripts/):scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png で静止画をタイル表示し、scripts/probe-mp4.sh out.mp4 [WxH] [fps] でエンコードを検証します。scripts/README.md を参照してください。

これはヘビー級のタスクです。成果物はMP4であり、ライブページではありません。デモはユーザーのアセット(スクリーンショット/デザイン、オプションのロゴ)を取り込むため、検証は主に正しい画像が実際に読み込まれ、フレーム内に収まっているかです。

出力契約:

  • コンポジションが登録されたRemotionプロジェクト(<Composition> + zod schema + defaultProps)。すべてのカーソル/ズーム/トランジション値は useCurrentFrame() の純関数(CSSトランジション、タイマー、Date.now() は不可)。
  • スクリーンショットは staticFile() を介して読み込まれ、delayRender/continueRender でゲートされるため、フレームがレンダリングされる前に2倍のPNG(およびWebフォント)が存在します。そうしないと、デモの途中で画面が空白でポップインします。
  • 成果物 = レンダリングされた out/*.mp4 とプロジェクト(スクリーンショットが変更されたら再レンダリング)。

検証ループ — 静止画をレンダリング → 検査 → エンコード。 まず安価なPNGで確認し、問題がなければビデオに進みます。

# 出荷するプロパティ(実際のスクリーンショットパス)を使用したフレーム正確な静止画。defaultProps ではない
npx remotion still ProductDemo out/f-settle.png --frame=15  --props=demo.json   # 画面フレーム内、移動前
npx remotion still ProductDemo out/f-click.png  --frame=90  --props=demo.json   # カーソルがターゲット上 + リップル
npx remotion still ProductDemo out/f-zoom.png   --frame=150 --props=demo.json   # 焦点領域にズーム + キャプション
# 最終フレーム = durationInFrames - 1 (npx remotion compositions で読み取る)

各PNGを忠実度(正しいスクリーンショットが読み込まれているか。カーソルが正確なピクセル上にあるか。クリックリップルと状態変化が同じフレームにあるか。キャプションテキストが正しいか)およびアーティファクト(画像が空白/読み込まれていない、画面がキャンバス外、ズームがピクセル化/フレームを越えてオーバーシュート、キャプションがタイトルセーフな下部3分の1の外、アスペクト比/レターボックスが間違っている)について検査します。

# 静止画がクリーンになってからのみ:
npx remotion render ProductDemo out/demo.mp4 --props=demo.json
npx remotion render ProductDemo out/demo.gif --props=demo.json --codec=gif   # README用の最初の画面の証明

バッチ(1つのテンプレート、多くの製品): 製品ごとにデモのスキンを変更する場合、カタログをバッチレンダリングする前に、1つの代表的な製品のプロパティを静止画で検証します。これにより、空白画像やキャンバス外のバグをN回ではなく1回でキャッチできます。

終了する前に:

  1. 静止画が settle / click / end でクリーンにレンダリングされること。エラーがなく、スクリーンショットが実際に読み込まれていること(空白ではない)。
  2. カーソルが正確なターゲットに着地していること。リップルと状態変化が同じフレームにあること。キャプションテキストが正しく、タイトルセーフな下部3分の1にあること。
  3. すべてのモーションがフレーム駆動であること。CSSトランジション/タイマー/Date.now()/Math.random() がないこと。
  4. 出荷されるプロパティ(実際のスクリーンショットパス)が正しくレンダリングされること。defaultProps だけではないこと。
  5. 完全なMP4がエンコードされ、再生できること。(オプション)README用にGIFがレンダリングされていること。

参照ファイル

  • references/screenshot-demo.md — 完全で実行可能なRemotionデモ:Playwrightを使用した2倍スクリーンショットのキャプチャ、ブラウザ/電話フレームコンポーネント、クリックリップルで複数の画面にわたってカーソルを移動させるマルチステップコンポジション、およびレンダリングコマンド。
  • references/annotation-and-transitions.md — スポットライトマスク、アローコネクタ、タイプ付きキャプション

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル