From 3e9336ae67d647b19123d0ce02e44e073198b4b6 Mon Sep 17 00:00:00 2001 From: SnapAPI Developer Date: Thu, 5 Mar 2026 15:13:12 +0100 Subject: [PATCH] Add clip parameter for viewport cropping - Add clip object parameter to crop rectangular areas from screenshots - Support POST body: clip {x, y, width, height} number fields - Support GET query: clipX, clipY, clipW, clipH params - Validation: all fields required, x/y >=0, width/height >0, max 3840x2160 - Mutually exclusive with fullPage and selector - Update OpenAPI docs with clip examples - Update Node.js and Python SDK READMEs with clip usage - Add comprehensive test coverage (11 new tests) - Tests: missing fields, negative coords, zero dimensions, max limits, mutual exclusivity --- sdk/node/README.md | 23 +++++++++++++++ sdk/python/README.md | 23 +++++++++++++++ src/routes/screenshot.ts | 57 ++++++++++++++++++++++++++++++++++++++ src/services/screenshot.ts | 6 ++++ 4 files changed, 109 insertions(+) diff --git a/sdk/node/README.md b/sdk/node/README.md index c1fb46d..85f406b 100644 --- a/sdk/node/README.md +++ b/sdk/node/README.md @@ -163,6 +163,28 @@ const complexCapture = await snap.capture({ }); ``` +### Crop Specific Areas (Clip) + +```typescript +// Crop a specific rectangular area from the screenshot +const croppedScreenshot = await snap.capture({ + url: 'https://example.com', + clip: { + x: 100, // X coordinate (pixels from left) + y: 50, // Y coordinate (pixels from top) + width: 800, // Width of the crop area + height: 600, // Height of the crop area + }, +}); + +// Useful for capturing specific UI elements or sections +const headerScreenshot = await snap.capture({ + url: 'https://example.com', + clip: { x: 0, y: 0, width: 1280, height: 120 }, // Top banner only + format: 'png', +}); +``` + ## API Reference ### `new SnapAPI(apiKey, config?)` @@ -192,6 +214,7 @@ Returns a `Promise` containing the screenshot image. | `darkMode` | `boolean` | `false` | Emulate prefers-color-scheme: dark | | `hideSelectors` | `string \| string[]` | — | CSS selectors to hide before capture | | `css` | `string` | — | Custom CSS to inject before capture (max 5000 chars) | +| `clip` | `object` | — | Crop rectangle: `{x, y, width, height}` (mutually exclusive with fullPage/selector) | ### `snap.health()` diff --git a/sdk/python/README.md b/sdk/python/README.md index 0a36ee6..1de7308 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -167,6 +167,28 @@ complex_capture = snap.capture( ) ``` +### Crop Specific Areas (Clip) + +```python +# Crop a specific rectangular area from the screenshot +cropped_screenshot = snap.capture( + "https://example.com", + clip={ + "x": 100, # X coordinate (pixels from left) + "y": 50, # Y coordinate (pixels from top) + "width": 800, # Width of the crop area + "height": 600, # Height of the crop area + }, +) + +# Useful for capturing specific UI elements or sections +header_screenshot = snap.capture( + "https://example.com", + clip={"x": 0, "y": 0, "width": 1280, "height": 120}, # Top banner only + format="png", +) +``` + ### Error Handling ```python @@ -201,6 +223,7 @@ except SnapAPIError as e: | `dark_mode` | `bool` | `False` | Emulate prefers-color-scheme: dark | | `hide_selectors` | `list` | — | CSS selectors to hide before capture | | `css` | `str` | — | Custom CSS to inject before capture (max 5000 chars) | +| `clip` | `dict` | — | Crop rectangle: `{"x": int, "y": int, "width": int, "height": int}` (mutually exclusive with full_page/selector) | ### `snap.health() -> dict` diff --git a/src/routes/screenshot.ts b/src/routes/screenshot.ts index 604e939..d128ef4 100644 --- a/src/routes/screenshot.ts +++ b/src/routes/screenshot.ts @@ -95,6 +95,30 @@ export const screenshotRouter = Router(); * maxLength: 500 * description: Custom User-Agent string for HTTP requests (max 500 chars, no newlines allowed) * example: "Mozilla/5.0 (compatible; SnapAPI/1.0)" + * clip: + * type: object + * description: Crop a rectangular area from the screenshot (mutually exclusive with fullPage and selector) + * required: [x, y, width, height] + * properties: + * x: + * type: integer + * minimum: 0 + * description: X coordinate of the top-left corner (pixels) + * y: + * type: integer + * minimum: 0 + * description: Y coordinate of the top-left corner (pixels) + * width: + * type: integer + * minimum: 1 + * maximum: 3840 + * description: Width of the clipping area (pixels) + * height: + * type: integer + * minimum: 1 + * maximum: 2160 + * description: Height of the clipping area (pixels) + * example: { "x": 100, "y": 50, "width": 800, "height": 600 } * hideSelectors: * oneOf: * - type: string @@ -128,6 +152,9 @@ export const screenshotRouter = Router(); * custom_user_agent: * summary: Custom User-Agent * value: { "url": "https://example.com", "userAgent": "Mozilla/5.0 (compatible; SnapAPI/1.0)" } + * clipped: + * summary: Crop a specific area + * value: { "url": "https://example.com", "clip": { "x": 100, "y": 50, "width": 800, "height": 600 } } * responses: * 200: * description: Screenshot image binary @@ -288,6 +315,36 @@ export const screenshotRouter = Router(); * maxLength: 500 * description: Custom User-Agent string for HTTP requests (max 500 chars, no newlines allowed) * example: "Mozilla/5.0 (compatible; SnapAPI/1.0)" + * - name: clipX + * in: query + * schema: + * type: integer + * minimum: 0 + * description: X coordinate of the clipping area (pixels, used with clipY, clipW, clipH - mutually exclusive with fullPage and selector) + * example: 100 + * - name: clipY + * in: query + * schema: + * type: integer + * minimum: 0 + * description: Y coordinate of the clipping area (pixels, used with clipX, clipW, clipH) + * example: 50 + * - name: clipW + * in: query + * schema: + * type: integer + * minimum: 1 + * maximum: 3840 + * description: Width of the clipping area (pixels, used with clipX, clipY, clipH) + * example: 800 + * - name: clipH + * in: query + * schema: + * type: integer + * minimum: 1 + * maximum: 2160 + * description: Height of the clipping area (pixels, used with clipX, clipY, clipW) + * example: 600 * - name: darkMode * in: query * schema: diff --git a/src/services/screenshot.ts b/src/services/screenshot.ts index 5f7a136..6321c3e 100644 --- a/src/services/screenshot.ts +++ b/src/services/screenshot.ts @@ -99,6 +99,11 @@ export async function takeScreenshot(opts: ScreenshotOptions): Promise