screenshot-generator

Generate screenshots for web audio apps (desktop, mobile landscape, mobile portrait) using Playwright. Also captures component-level screenshots for documentation.

SKILL.md

GitHub

๐Ÿ“ธ Screenshot Generator Skill

์›น ์•ฑ์˜ ์Šคํฌ๋ฆฐ์ƒท์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽฏ ์šฉ๋„

  • README.md ๋ฐ ๋ฌธ์„œ์šฉ ์Šคํฌ๋ฆฐ์ƒท ์ƒ์„ฑ
  • Desktop, Mobile Landscape, Mobile Portrait ๋ทฐ ์บก์ฒ˜
  • ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ(ํ—ค๋”, ํŒจ๋“œ, ๋…ธ๋ธŒ ๋“ฑ) ์Šคํฌ๋ฆฐ์ƒท

๐Ÿ“ ํŒŒ์ผ ๊ตฌ์กฐ

screenshot-generator/
โ”œโ”€โ”€ SKILL.md              # ์ด ํŒŒ์ผ
โ””โ”€โ”€ scripts/
    โ””โ”€โ”€ generate_screenshots.js  # ๋ฉ”์ธ ์Šคํฌ๋ฆฝํŠธ

โš™๏ธ ์š”๊ตฌ์‚ฌํ•ญ

# Playwright ์„ค์น˜
npm install playwright
npx playwright install chromium

๐Ÿš€ ์‚ฌ์šฉ๋ฒ•

๊ธฐ๋ณธ ์‹คํ–‰

# ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์—์„œ
node scripts/generate_screenshots.js

์Šคํฌ๋ฆฝํŠธ ๋™์ž‘

  1. ๋กœ์ปฌ ์„œ๋ฒ„ ์‹œ์ž‘: http-server๋กœ ์•ฑ ์„œ๋น™ (ํฌํŠธ 8080)
  2. ๋ธŒ๋ผ์šฐ์ € ์‹คํ–‰: Playwright Chromium
  3. ์Šคํฌ๋ฆฐ์ƒท ์บก์ฒ˜:
    • screenshot-desktop.png (1280x800)
    • screenshot-mobile-landscape.png (844x390)
    • screenshot-mobile-portrait.png (iPhone 13 Pro)
  4. ์ปดํฌ๋„ŒํŠธ ์บก์ฒ˜: ๊ฐœ๋ณ„ UI ์š”์†Œ
  5. ์„œ๋ฒ„ ์ข…๋ฃŒ

์ถœ๋ ฅ ์œ„์น˜

์Šคํฌ๋ฆฐ์ƒท์€ assets/ ํด๋”์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”ง ํ”„๋กœ์ ํŠธ๋ณ„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

๊ฐ ํ”„๋กœ์ ํŠธ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ  ํ•„์š”์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์„ธ์š”:

ํ•„์ˆ˜ ์ˆ˜์ • ์‚ฌํ•ญ

// 1. ์„œ๋ฒ„ ํฌํŠธ (ํ•„์š”์‹œ)
const server = spawn('npx', ['-y', 'http-server', '-p', '8080', '-a', '127.0.0.1']);

// 2. ๋Œ€๊ธฐํ•  UI ์š”์†Œ (ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ๋‹ค๋ฆ„)
await page.waitForSelector('.your-main-element', { timeout: 10000 });

// 3. ์ปดํฌ๋„ŒํŠธ ์…€๋ ‰ํ„ฐ (ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ๋‹ค๋ฆ„)
const header = page.locator('.your-header-class');
await header.screenshot({ path: path.join(assetsDir, 'header.png') });

์ƒˆ ์Šคํฌ๋ฆฐ์ƒท ์ถ”๊ฐ€

// ์Šคํฌ๋ฆฝํŠธ ํ•˜๋‹จ์— ์ถ”๊ฐ€
console.log('Taking New Feature Screenshot...');
const newFeature = page.locator('.your-selector');
await newFeature.screenshot({ path: path.join(assetsDir, 'new-feature.png') });

๐Ÿ“‹ ํ”„๋กœ์ ํŠธ๋ณ„ ์„ค์ • ์˜ˆ์‹œ

acidBros

// ๋Œ€๊ธฐํ•  ์š”์†Œ
await page.waitForSelector('.step-303', { timeout: 10000 });
await page.waitForSelector('.step-909', { timeout: 10000 });
await page.waitForSelector('.rotary-knob', { timeout: 10000 });

// ์ปดํฌ๋„ŒํŠธ
const transport = page.locator('.top-bar');
const tb303 = page.locator('.machine.tb-303').first();
const tr909 = page.locator('.machine.tr-909');

ddxx7

// ๋Œ€๊ธฐํ•  ์š”์†Œ
await page.waitForSelector('.operator-panel', { timeout: 10000 });
await page.waitForSelector('.algorithm-matrix', { timeout: 10000 });

// ์ปดํฌ๋„ŒํŠธ
const header = page.locator('header');
const operatorPanel = page.locator('.operator-panel');
const libraryView = page.locator('.library-view');

uss44

// ๋Œ€๊ธฐํ•  ์š”์†Œ
await page.waitForSelector('.pad-grid', { timeout: 10000 });
await page.waitForSelector('.waveform-editor', { timeout: 10000 });

// ์ปดํฌ๋„ŒํŠธ
const header = page.locator('header');
const padGrid = page.locator('.pad-grid');
const paramsPanel = page.locator('.params-panel');

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ

  1. ์„œ๋ฒ„ ์ถฉ๋Œ: ์ด๋ฏธ 8080 ํฌํŠธ๊ฐ€ ์‚ฌ์šฉ ์ค‘์ด๋ฉด ์‹คํŒจ
  2. ํƒ€์ž„์•„์›ƒ: ๋„คํŠธ์›Œํฌ ๋А๋ฆฌ๋ฉด waitForSelector ํƒ€์ž„์•„์›ƒ ์ฆ๊ฐ€ ํ•„์š”
  3. ํ—ค๋“œ๋ฆฌ์Šค: ๊ธฐ๋ณธ์ ์œผ๋กœ headless ๋ชจ๋“œ (ํ™”๋ฉด ํ‘œ์‹œ ์—†์Œ)

๐Ÿ”— ๊ด€๋ จ ๋ฌธ์„œ