[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-4c470522-be52-48aa-af27-904a37f4fbb9":3,"$flNqEcBN0LqrYz7kNdruw1rNulFTDAoNB2HuuTOjFkLQ":44},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":34},"4c470522-be52-48aa-af27-904a37f4fbb9","full-page-screenshot","使用时，当用户请求捕获全页截图、长截图或网页完整页面时。通过Chrome DevTools Protocol处理SPA滚动容器、懒加载图片和非常高的页面，无外部依赖。","cat_design_graphic","mod_design","alirezarezvani,design","---\nname: \"full-page-screenshot\"\ndescription: \"Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external dependencies.\"\n---\n\n# Full Page Screenshot\n\nCapture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.\n\n## Prerequisites\n\n- **Node.js 22+** (uses built-in `WebSocket`)\n- **Chrome\u002FChromium** with remote debugging enabled\n\nCheck environment readiness:\n\n```bash\nnode \"${SKILL_DIR}\u002Fscripts\u002Ffull-page-screenshot.mjs\" --check\n```\n\nIf Chrome check fails, instruct user to open `chrome:\u002F\u002Finspect\u002F#remote-debugging` and enable **\"Allow remote debugging for this browser instance\"**.\n\n## Workflow\n\n### Option A: Screenshot an already-open tab (recommended for authenticated pages)\n\n1. List available tabs:\n\n```bash\nnode \"${SKILL_DIR}\u002Fscripts\u002Ffull-page-screenshot.mjs\" --list\n```\n\n2. Identify the target by title\u002FURL, then capture:\n\n```bash\nnode \"${SKILL_DIR}\u002Fscripts\u002Ffull-page-screenshot.mjs\" \u003CtargetId> \u002Ftmp\u002Fscreenshot.png --width 1200 --dpr 1\n```\n\n### Option B: Screenshot a URL (opens a background tab, captures, closes)\n\n```bash\nnode \"${SKILL_DIR}\u002Fscripts\u002Ffull-page-screenshot.mjs\" --url \"https:\u002F\u002Fexample.com\" \u002Ftmp\u002Fscreenshot.png --width 1200 --dpr 1 --wait 15000\n```\n\n> **Note:** `--url` mode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.\n\n### Parameters\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `output` | Output PNG file path | `\u002Ftmp\u002Fscreenshot.png` |\n| `--width` | Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 |\n| `--dpr` | Device pixel ratio (2 = Retina, but 4x file size) | 1 |\n| `--wait` | Page load timeout in ms (`--url` mode only) | 15000 |\n| `--css` | Custom CSS to inject before capture (e.g., hide elements) | — |\n\n### Verify Output\n\n```bash\n# macOS\nsips -g pixelWidth -g pixelHeight \u002Ftmp\u002Fscreenshot.png\n\n# Linux\nfile \u002Ftmp\u002Fscreenshot.png\n```\n\n## Core Capabilities\n\n1. **SPA scroll container expansion** — Detects `overflow-y: auto\u002Fscroll` containers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind `h-[calc(...)]`) so all content renders in a single pass.\n\n2. **DOM stability detection** — After `readyState=complete`, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.\n\n3. **Lazy-load triggering** — Scrolls the viewport incrementally to fire `IntersectionObserver` callbacks, then waits for all `\u003Cimg>` elements to complete loading.\n\n4. **Tiled capture for very tall pages** — Pages exceeding 16,000px are captured in 8,000px tiles and automatically stitched using Python PIL. Falls back to saving tiles separately if PIL is unavailable.\n\n5. **Auto-discovery of Chrome** — Reads `DevToolsActivePort` file to find the debugging port. Falls back to probing ports 9222, 9229, 9333.\n\n6. **CDP Proxy fallback** — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (`\u002Feval`, `\u002Fscreenshot`, `\u002Fscroll`) for capture.\n\n## How It Works\n\n```\n1. Discover Chrome debugging port\n2. Connect via WebSocket (CDP)\n3. Attach to target \u002F create background tab\n4. Set viewport width via Emulation domain\n5. Wait: readyState + DOM stability\n6. Detect & expand scroll containers\n7. Scroll through page (trigger lazy-load)\n8. Wait for images to complete\n9. Measure final content height\n10. Page.captureScreenshot (or tiled capture)\n11. Stitch tiles if needed (PIL)\n12. Restore viewport, detach, clean up\n```\n\n## Anti-Patterns\n\n| Do NOT | Do instead |\n|--------|-----------|\n| Use `--dpr 2` on pages > 10,000px tall | Use `--dpr 1` to avoid Chrome memory issues |\n| Use `--url` for authenticated\u002FSSO pages | Use `--list` + targetId on a tab where user is logged in |\n| Set `--wait` below 5000 for SPAs | SPAs need time to fetch data and render; use 10000-15000 |\n| Capture without checking `--check` first | Always verify Chrome debugging is available |\n| Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards\u002Ftables |\n| Skip output verification | Always verify with `sips` or `file` command after capture |\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| \"Cannot find Chrome debugging port\" | Remote debugging not enabled | Open `chrome:\u002F\u002Finspect\u002F#remote-debugging`, enable it |\n| \"WebSocket connection timeout\" | CDP proxy holding the connection | Script auto-falls back to proxy API |\n| Blank\u002Fwhite screenshot | Page not loaded yet | Increase `--wait` value |\n| Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists |\n| Out of memory | Very tall page + high DPR | Reduce `--dpr` to 1 and\u002For reduce `--width` |\n| \"PIL not available for stitching\" | Python Pillow not installed | Install with `pip3 install Pillow` or accept separate tile files |\n\n## Cross-References\n\n- [`engineering\u002Fbrowser-automation`](..\u002Fbrowser-automation\u002FSKILL.md) — General browser automation patterns via CDP\u002FPlaywright\n- [`engineering\u002Fperformance-profiler`](..\u002Fperformance-profiler\u002FSKILL.md) — Performance analysis that may complement visual captures\n","","imported","https:\u002F\u002Fgithub.com\u002Falirezarezvani\u002Fclaude-skills","user_system_seed","SkillOPIC",true,144,247,"2026-05-16 13:54:01",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"设计创意","design","mdi-palette-outline","UI 设计、生成艺术、品牌视觉等创意 Skill",3,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":32,"skillCount":33,"createdAt":26},"视觉创意","graphic","mdi-brush","海报、Logo、插画等视觉创作",2,48,[35],{"id":36,"skillId":4,"version":37,"fileName":38,"fileSize":39,"filePath":40,"fileHash":41,"manifest":42,"createdAt":43},"67b1581c-e714-42ab-b27f-11b8008ce0d3","1.0.0","full-page-screenshot.zip",11607,"uploads\u002Fskills\u002F4c470522-be52-48aa-af27-904a37f4fbb9\u002Ffull-page-screenshot.zip","26ff343afb495732e87a8f791efcb99153434a3bbeaa0dbce89cc7f4d1678ef8","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":5508},{\"path\":\"scripts\u002Ffull-page-screenshot.mjs\",\"isDirectory\":false,\"size\":35910}]","2026-05-16 13:54:02",{"code":45,"message":46,"data":47},200,"success",{"items":48,"stats":49,"page":52},[],{"averageRating":50,"totalRatings":50,"ratingCounts":51},0,[50,50,50,50,50],{"limit":53,"offset":50,"hasMore":54,"nextOffset":53,"ratedOnly":16},15,false]