mcpField
S
screenshots

screenshots

github.com/sickn33营销与增长48.7k239 次安装今天更新
代码仓库

关于 screenshots

screenshots 是一项使用 Playwright 捕获应用截图的技能,适用于营销、社交媒体、落地页或文档。它指导确定 URL、收集需求、检查应用并生成 HiDPI 截图。

主要功能

  1. 01Playwright 截图流程
  2. 022 倍 HiDPI 捕获
  3. 03收集 URL 与截图需求
  4. 04检查代码库和路由
  5. 05截图故障排查指导

适用场景

  1. 01准备 Product Hunt 应用图片
  2. 02制作社交媒体视觉素材
  3. 03捕获落地页截图
  4. 04记录应用界面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill screenshots

安装后在 Claude Code 中输入/screenshots确认已加载。

详细介绍

截图

直接使用 Playwright 为你的应用生成营销级截图。截图将以真正的 HiDPI(2x Retina)分辨率捕获,使用 deviceScaleFactor: 2。

何时使用此技能

在以下情况下使用此技能:

  • 用户想为 Product Hunt 创建截图
  • 为社交媒体创建截图
  • 为落地页生成图片
  • 创建文档截图
  • 用户请求制作营销级应用截图

先决条件

必须可以使用 Playwright。检查是否已安装:

npm ls playwright @playwright/test --depth=0

如果未找到,请告知用户:

必须安装 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 的文件夹都是一个路由
Next.js Pages Routerpages/ 目录每个文件都是一个路由
Railsconfig/routes.rb读取整个文件以获取所有路由
React Router搜索 createBrowserRouter 或 <Route带路径的路由定义
Vue Routersrc/router/index.js 或 router.js带路径定义的路由数组
SvelteKitsrc/routes/ 目录每个包含 +page.svelte 的文件夹都是一个路由
Remixapp/routes/ 目录基于文件的路由
Laravelroutes/web.php路由定义
Djangourls.py 文件URL 模式
Express搜索 app.get、router.get路由处理程序

重要:实际读取这些文件,不要只是检查它们是否存在。路由定义会告诉你哪些页面可用于截图。

3.3:识别关键组件

查找代表可截图功能的组件:

  • 仪表板组件
  • 具有独特 UI 的功能区块
  • 表单和交互式输入
  • 数据可视化(图表、图形、表格)
  • 模态框和对话框
  • 导航和侧边栏
  • 设置面板
  • 用户个人资料区块
3.4:检查营销资产

查找暗示关键功能的现有营销内容:

  • 落地页组件(通常位于 components/landing/ 或 components/marketing/)
  • 功能列表组件
  • 定价表
  • 用户评价区块
3.5:构建功能列表

创建已发现功能的全面列表,包含:

  • 功能名称(来自 README 或组件名称)
  • URL 路径(来自路由)
  • 要聚焦的 CSS 选择器(来自组件结构)
  • 所需的 UI 状态(已登录、已填充数据、模态框已打开、已选择特定标签页)

第 4 步:与用户一起规划截图

向用户展示已发现的功能,并请他们确认或修改列表。

使用 AskUserQuestion:

  • Header:"Features"
  • Question:"I found these features in your codebase. Which would you like to screenshot?"
  • Options:列出发现的 3-4 个关键功能,外加 "Let me pick specific ones"

如果用户想要特定的功能,请提出后续问题以明确具体要截取的内容。

第 5 步:创建截图目录

mkdir -p screenshots

第 6 步:生成并运行 Playwright 脚本

创建一个使用 Playwright 并具有正确 HiDPI 设置的 Node.js 脚本。该脚本应:

  1. 使用 deviceScaleFactor: 2 以获得真正的 retina 分辨率
  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: false, // set true only for an authorized test account
  loginUrl: '[LOGIN_URL]',
  email: process.env.SCREENSHOT_EMAIL,
  password: process.env.SCREENSHOT_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(new URL(AUTH.loginUrl, BASE_URL).href);

    // 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.waitForURL('[EXPECTED_AUTHENTICATED_URL]'); // replace with verified app route
    console.log('Authenticated route reached');
  }

  // 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(error => { console.error(error); process.exitCode = 1; });
运行脚本
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. 等待内容加载:使用应用专属的就绪选择器;网络空闲并不能证明内容已就绪
  4. 隐藏开发工具:确保画面中没有浏览器扩展或开发覆盖层
  5. 深色模式变体:如果支持,可考虑同时截取浅色和深色模式

限制

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为环境特定验证、测试或专家审查的替代品。
  • 如果缺少必要输入、权限、安全边界或成功标准,请暂停并请求澄清。

该脚本只是可自定义的示例。提交凭据前请确认定位器正确;通用的首个匹配项选择器可能会选中错误的表单。屏幕截图权限并不代表有权修改账户、发布图像或截取第三方私人数据。请使用演示数据,并检查/编辑每张图像以移除敏感信息。在输出目录中验证截图文件名,并避免覆盖现有文件。整页/元素尺寸与视口示例不同;请验证实际像素尺寸。生产工具应在 finally 块中关闭浏览器。

评论

支持 Markdown