mcpField
S
screenshots

screenshots

github.com/steveclarkeマーケティング・グロース3678 回インストール1 日前に更新
リポジトリ

screenshots について

screenshotsは、Playwrightでアプリのマーケティング用スクリーンショットを撮るスキルです。製品紹介やSNS、ドキュメント向けに、2倍HiDPIでの撮影とルートからの撮影候補の把握を支援します。

主な機能

  1. 01Playwrightでアプリ画面を撮影
  2. 022倍HiDPI解像度で撮影
  3. 03ルートを分析してページを発見
  4. 04ログイン後の画面撮影に対応
  5. 05撮影時のトラブル対応を案内

活用シーン

  1. 01製品リリース用画像の作成
  2. 02SNS向け機能画像の準備
  3. 03ランディングページ素材の作成
  4. 04ドキュメント用UI参考画像の作成

インストール

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

$npx skills add https://github.com/steveclarke/dotfiles --skill screenshots

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

詳細

Playwright を直接使用して、アプリのマーケティング品質のスクリーンショットを生成します。スクリーンショットは、deviceScaleFactor: 2 を使用して、真の HiDPI(2x Retina)解像度で撮影されます。

前提条件

Playwright が利用可能である必要があります。次のコマンドで確認します。

npx playwright --version 2>/dev/null || npm ls playwright 2>/dev/null | grep playwright

見つからない場合は、ユーザーに次のように伝えます。

Playwright が必要です。npm install -D playwright または npm install -D @playwright/test でインストールしてください。

ステップ 1:アプリの URL を決定する

$1 が指定されている場合は、それをアプリの URL として使用します。

URL が指定されていない場合:

  1. package.json のスクリプトを確認し、開発サーバーが起動している可能性があるか調べます
  2. AskUserQuestion を使用して、ユーザーに URL を尋ねるか、開発サーバーの起動を手伝うことを提案します

候補として提示する一般的なデフォルト URL:

  • http://localhost:3000(Next.js、Create React App、Rails)
  • http://localhost:5173(Vite)
  • http://localhost:4000(Phoenix)
  • http://localhost:8080(Vue CLI、汎用)

ステップ 2:要件を確認する

次の質問を使用して、AskUserQuestion を実行します。

質問 1:スクリーンショットの枚数

  • ヘッダー:「枚数」
  • 質問:「スクリーンショットは何枚必要ですか?」
  • 選択肢:
    • 「3~5」 - 主要機能を手早くまとめたセット
    • 「5~10」 - 機能を幅広く網羅
    • 「10 以上」 - マーケティング用のフルセット

質問 2:用途

  • ヘッダー:「用途」
  • 質問:「これらのスクリーンショットは何に使用しますか?」
  • 選択肢:
    • 「Product Hunt」 - ヒーロー画像と機能のハイライト
    • 「ソーシャルメディア」 - 目を引く機能デモ
    • 「ランディングページ」 - マーケティング用セクションとメリット
    • 「ドキュメント」 - UI リファレンスとチュートリアル

質問 3:認証

  • ヘッダー:「認証」
  • 質問:「スクリーンショットを撮りたい機能にアクセスするには、アプリへのログインが必要ですか?」
  • 選択肢:
    • 「ログイン不要」 - 公開ページのみ
    • 「必要。認証情報を提供します」 - 最初にログインが必要

ユーザーが「必要。認証情報を提供します」を選択した場合は、次の追加質問をします。

  • 「ログインページの URL は何ですか?」(例:/login、/sign-in)
  • 「メールアドレス/ユーザー名は何ですか?」
  • 「パスワードは何ですか?」

スクリプトは Playwright のスマートロケーターを使用して、ログインフォームのフィールドを自動的に検出します。

ステップ 3:機能を把握するためにコードベースを分析する

コードベースを詳しく調べてアプリを理解し、スクリーンショットの候補を特定します。

3.1:まずドキュメントを読む

アプリの機能を理解するため、必ず最初に次のファイルを読みます。

  1. README.md(およびサブディレクトリ内の README ファイル) - README 全体を読み、次の点を把握します。

    • アプリの概要と解決する課題
    • 主な機能とできること
    • すでに記載されているスクリーンショットや機能の説明
  2. CHANGELOG.md または HISTORY.md - 最近追加された、紹介する価値のある機能

  3. docs/ ディレクトリ - 機能に関する追加ドキュメント

3.2:ルートを分析してページを特定する

ルーティング設定を読み、利用可能なすべてのページを確認します。

フレームワーク読み込むファイル確認する内容
Next.js App Routerapp/ ディレクトリの構成page.tsx を含む各フォルダーが 1 つのルートです
Next.js Pages Routerpages/ ディレクトリ各ファイルが 1 つのルートです
Railsconfig/routes.rbすべてのルートを確認するため、ファイル全体を読みます
React RoutercreateBrowserRouter または <Route を検索パスを含むルート定義
Vue Routersrc/router/index.js または router.jsパス定義を含むルート配列
SvelteKitsrc/routes/ ディレクトリ+page.svelte を含む各フォルダーが 1 つのルートです
Remixapp/routes/ ディレクトリファイルベースのルーティング
Laravelroutes/web.phpルート定義
Djangourls.py ファイルURL パターン
Expressapp.get、router.get を検索ルートハンドラー

重要:ファイルが存在するかどうかを確認するだけでなく、実際にファイルを読みます。ルート定義から、スクリーンショットを撮影できるページを特定できます。

3.3:主要なコンポーネントを特定する

スクリーンショットで撮影できる機能を表すコンポーネントを探します。

  • ダッシュボードのコンポーネント
  • 独自の UI を持つ機能セクション
  • フォームとインタラクティブな入力欄
  • データの可視化(チャート、グラフ、テーブル)
  • モーダルとダイアログ
  • ナビゲーションとサイドバー
  • 設定パネル
  • ユーザープロフィールのセクション
3.4:マーケティング素材を確認する

主要な機能の手がかりとなる既存のマーケティングコンテンツを探します。

  • ランディングページのコンポーネント(多くの場合、components/landing/ または components/marketing/ にあります)
  • 機能一覧のコンポーネント
  • 料金表
  • お客様の声のセクション
3.5:機能一覧を作成する

見つかった機能の包括的な一覧を、以下の情報とともに作成します。

  • 機能名(README またはコンポーネント名から取得)
  • URL パス(ルートから取得)
  • フォーカスする CSS セレクター(コンポーネントの構造から取得)
  • 必要な UI の状態(ログイン済み、データ入力済み、モーダル表示中、特定のタブ選択中など)

ステップ 4:ユーザーとスクリーンショットを計画する

見つかった機能をユーザーに提示し、一覧の確認または変更を依頼します。

AskUserQuestion を使用します。

  • ヘッダー:「機能」
  • 質問:「コードベースで以下の機能が見つかりました。どの機能のスクリーンショットを撮影しますか?」
  • 選択肢:見つかった主要な機能を3〜4個と、「撮影する機能を自分で選ぶ」を提示します

ユーザーが特定の機能を希望する場合は、撮影する内容を正確に確認するため、追加の質問をします。

ステップ 5:スクリーンショット用ディレクトリを作成する

mkdir -p screenshots

ステップ 6:Playwright スクリプトを作成して実行する

適切な HiDPI 設定で Playwright を使用する Node.js スクリプトを作成します。スクリプトでは次の処理を行います。

  1. 真の Retina 解像度を実現するため、deviceScaleFactor: 2 を使用する
  2. ビューポートを 1440x900 に設定する(2880x1800 ピクセルの画像が生成されます)
  3. 認証情報が提供されている場合は、認証を処理する
  4. 各ページに移動してスクリーンショットを撮影する
スクリプトのテンプレート

このスクリプトを一時ファイル(例:screenshot-script.mjs)に書き込み、実行します。

import { chromium } from 'playwright';

const BASE_URL = '[APP_URL]';
const SCREENSHOTS_DIR = './screenshots';

// Authentication config (if needed)
const AUTH = {
  needed: [true|false],
  loginUrl: '[LOGIN_URL]',
  email: '[EMAIL]',
  password: '[PASSWORD]',
};

// Screenshots to capture
const SCREENSHOTS = [
  { name: '01-feature-name', url: '/path', waitFor: '[optional-selector]' },
  { name: '02-another-feature', url: '/another-path' },
  // ... add all planned screenshots
];

async function main() {
  const browser = await chromium.launch();

  // Create context with HiDPI settings
  const context = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    deviceScaleFactor: 2,  // This is the key for true retina screenshots
  });

  const page = await context.newPage();

  // Handle authentication if needed
  if (AUTH.needed) {
    console.log('Logging in...');
    await page.goto(AUTH.loginUrl);

    // Smart login: try multiple common patterns for email/username field
    const emailField = page.locator([
      'input[type="email"]',
      'input[name="email"]',
      'input[id="email"]',
      'input[placeholder*="email" i]',
      'input[name="username"]',
      'input[id="username"]',
      'input[type="text"]',
    ].join(', ')).first();
    await emailField.fill(AUTH.email);

    // Smart login: try multiple common patterns for password field
    const passwordField = page.locator([
      'input[type="password"]',
      'input[name="password"]',
      'input[id="password"]',
    ].join(', ')).first();
    await passwordField.fill(AUTH.password);

    // Smart login: try multiple common patterns for submit button
    const submitButton = page.locator([
      'button[type="submit"]',
      'input[type="submit"]',
      'button:has-text("Sign in")',
      'button:has-text("Log in")',
      'button:has-text("Login")',
      'button:has-text("Submit")',
    ].join(', ')).first();
    await submitButton.click();

    await page.waitForLoadState('networkidle');
    console.log('Login complete');
  }

  // Capture each screenshot
  for (const shot of SCREENSHOTS) {
    console.log(`Capturing: ${shot.name}`);
    await page.goto(`${BASE_URL}${shot.url}`);
    await page.waitForLoadState('networkidle');

    // Optional: wait for specific element
    if (shot.waitFor) {
      await page.waitForSelector(shot.waitFor);
    }

    // Optional: perform actions before screenshot
    if (shot.actions) {
      for (const action of shot.actions) {
        if (action.click) await page.click(action.click);
        if (action.fill) await page.fill(action.fill.selector, action.fill.value);
        if (action.wait) await page.waitForTimeout(action.wait);
      }
    }

    await page.screenshot({
      path: `${SCREENSHOTS_DIR}/${shot.name}.png`,
      fullPage: shot.fullPage || false,
    });
    console.log(`  Saved: ${shot.name}.png`);
  }

  await browser.close();
  console.log('Done!');
}

main().catch(console.error);
スクリプトの実行
node screenshot-script.mjs

実行後、一時スクリプトを削除します。

rm screenshot-script.mjs

ステップ 7:スクリーンショットの高度なオプション

要素にフォーカスしたスクリーンショット

ビューポート全体ではなく、特定の要素のスクリーンショットを撮影するには、次のようにします。

const element = await page.locator('[CSS_SELECTOR]');
await element.screenshot({ path: `${SCREENSHOTS_DIR}/element.png` });
ページ全体のスクリーンショット

スクロール可能なコンテンツは、ページ全体を撮影します。

await page.screenshot({
  path: `${SCREENSHOTS_DIR}/full-page.png`,
  fullPage: true
});
アニメーションの待機

ページにアニメーションがある場合は、完了するまで待機します。

await page.waitForTimeout(500); // Wait 500ms for animations
スクリーンショットの撮影前に要素をクリックする

モーダル、ドロップダウン、またはホバー状態を撮影するには、次のようにします。

await page.click('button.open-modal');
await page.waitForSelector('.modal-content');
await page.screenshot({ path: `${SCREENSHOTS_DIR}/modal.png` });
ダークモードのスクリーンショット

アプリがダークモードに対応している場合は、次のようにします。

// Set dark mode preference
const context = await browser.newContext({
  viewport: { width: 1440, height: 900 },
  deviceScaleFactor: 2,
  colorScheme: 'dark',
});

ステップ 8:ファイル名の規則

順序を示す数字の接頭辞を付け、内容がわかる kebab-case のファイル名を使用します。

機能ファイル名
ダッシュボードの概要01-dashboard-overview.png
リンク管理02-link-inbox.png
エディションエディター03-edition-editor.png
分析04-analytics.png
設定05-settings.png

ステップ 9:確認して要約する

すべてのスクリーンショットを撮影したら、結果を確認します。

ls -la screenshots/*.png
sips -g pixelWidth -g pixelHeight screenshots/*.png 2>/dev/null || file screenshots/*.png

次の内容をユーザーに要約して伝えます。

  1. 生成されたすべてのファイルとそのパスを一覧表示する
  2. 解像度を確認する(ビューポートが 1440x900 の場合、2x Retina で 2880x1800 になります)
  3. ファイルサイズの合計を伝える
  4. 追加で行える操作を提案する

出力例:

Generated 5 marketing screenshots:

screenshots/
├── 01-dashboard-overview.png (1.2 MB, 2880x1800 @ 2x)
├── 02-link-inbox.png (456 KB, 2880x1800 @ 2x)
├── 03-edition-editor.png (890 KB, 2880x1800 @ 2x)
├── 04-analytics.png (567 KB, 2880x1800 @ 2x)
└── 05-settings.png (234 KB, 2880x1800 @ 2x)

All screenshots are true retina-quality (2x deviceScaleFactor) and ready for marketing use.

エラー処理

  • Playwright が見つからない:npm install -D playwright を提案します
  • ページが読み込まれない:開発サーバーが実行中か確認し、起動するよう提案します
  • ログインに失敗する:スマートロケーターは一般的なパターンを試しますが、一般的でないログインフォームでは失敗する場合があります。ログインに失敗した場合は、ログインページの HTML を調べて正しいセレクターを見つけ、スクリプトをカスタマイズします。
  • 要素が見つからない:CSS セレクターを確認し、代わりにページ全体のスクリーンショットを撮影することを提案します
  • スクリーンショットの撮影に失敗する:ディスク容量と、スクリーンショット用ディレクトリへの書き込み権限を確認します

最良の結果を得るためのヒント

  1. クリーンな UI 状態:現実的なコンテンツを表示するには、デモデータまたはシードデータを使用します
  2. サイズを統一:すべてのスクリーンショットで同じビューポートを使用します
  3. コンテンツの読み込みを待機:すべてのコンテンツが読み込まれるように、waitForLoadState('networkidle') を使用します
  4. 開発ツールを非表示:ブラウザー拡張機能や開発用オーバーレイが表示されていないことを確認します
  5. ダークモードのバリエーション:対応している場合は、ライトモードとダークモードの両方で撮影することを検討します

コメント