autokap 1.8.4 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-runner.js +1 -0
- package/dist/mockup.d.ts +12 -0
- package/dist/mockup.js +38 -8
- package/dist/web-playwright-local.js +0 -0
- package/package.json +1 -1
package/dist/cli-runner.js
CHANGED
|
@@ -1107,6 +1107,7 @@ async function prepareScreenshotBufferForDirectUpload(input, metadata, program,
|
|
|
1107
1107
|
}
|
|
1108
1108
|
output = await applyDeviceFrame(output, variantSpec.deviceFrame, {
|
|
1109
1109
|
orientation: inferCliOrientation(metadata.viewport ?? null),
|
|
1110
|
+
viewport: metadata.viewport ?? undefined,
|
|
1110
1111
|
colorScheme: metadata.theme,
|
|
1111
1112
|
outputScale: normalizeCliDeviceScaleFactor(metadata.deviceScaleFactor)
|
|
1112
1113
|
?? normalizeCliDeviceScaleFactor(program.outputScale)
|
package/dist/mockup.d.ts
CHANGED
|
@@ -191,6 +191,18 @@ export interface MockupOptions {
|
|
|
191
191
|
};
|
|
192
192
|
/** Explicit color scheme override — bypasses auto-detection from edge colors */
|
|
193
193
|
colorScheme?: 'light' | 'dark';
|
|
194
|
+
/**
|
|
195
|
+
* Viewport the screenshot was captured at (logical CSS px). For frameless
|
|
196
|
+
* browser mockups this drives the frame geometry so the content area matches
|
|
197
|
+
* the capture aspect ratio — without it, captures taken at a custom preset
|
|
198
|
+
* viewport get stretched by the fit:'fill' resize into the device config's
|
|
199
|
+
* logical dimensions. Ignored for devices with a frame asset (their screen
|
|
200
|
+
* rect is fixed by the asset).
|
|
201
|
+
*/
|
|
202
|
+
viewport?: {
|
|
203
|
+
width: number;
|
|
204
|
+
height: number;
|
|
205
|
+
};
|
|
194
206
|
}
|
|
195
207
|
export interface ResolvedDeviceFrameDescriptor {
|
|
196
208
|
id: string;
|
package/dist/mockup.js
CHANGED
|
@@ -94,6 +94,22 @@ function normalizeBrowserCornerRadius(cornerRadius, dpr) {
|
|
|
94
94
|
}
|
|
95
95
|
return cornerRadius * dpr;
|
|
96
96
|
}
|
|
97
|
+
// Bounds for capture viewports consumed by mockup geometry. The execution
|
|
98
|
+
// schema only enforces positive integers, so clamp here to keep the physical
|
|
99
|
+
// canvas (logical × outputScale ≤ 4) under sharp's ~32767px dimension limit.
|
|
100
|
+
const MIN_MOCKUP_VIEWPORT_PX = 16;
|
|
101
|
+
const MAX_MOCKUP_VIEWPORT_PX = 7680;
|
|
102
|
+
/** Validate a capture viewport for mockup geometry. Returns null when unusable. */
|
|
103
|
+
function sanitizeMockupViewport(viewport) {
|
|
104
|
+
const width = viewport?.width;
|
|
105
|
+
const height = viewport?.height;
|
|
106
|
+
if (!Number.isFinite(width) || !Number.isFinite(height))
|
|
107
|
+
return null;
|
|
108
|
+
if (width <= 0 || height <= 0)
|
|
109
|
+
return null;
|
|
110
|
+
const clamp = (value) => Math.max(MIN_MOCKUP_VIEWPORT_PX, Math.min(MAX_MOCKUP_VIEWPORT_PX, Math.round(value)));
|
|
111
|
+
return { width: clamp(width), height: clamp(height) };
|
|
112
|
+
}
|
|
97
113
|
/**
|
|
98
114
|
* Resolve the orientation config for a given orientation.
|
|
99
115
|
* Prefers per-orientation configs; falls back to rotation logic for legacy format.
|
|
@@ -526,9 +542,14 @@ export async function applyDeviceFrame(screenshot, deviceId, options) {
|
|
|
526
542
|
frameHeight: geometry.frameHeight,
|
|
527
543
|
screenRect: geometry.screenRect,
|
|
528
544
|
};
|
|
529
|
-
// For frameless browser devices:
|
|
530
|
-
//
|
|
531
|
-
//
|
|
545
|
+
// For frameless browser devices: build the frame around the capture viewport
|
|
546
|
+
// when provided (exact inverse of computeMockupLayout's content-area math, so
|
|
547
|
+
// the content area maps 1:1 to the screenshot and fit:'fill' cannot distort
|
|
548
|
+
// captures taken at a custom preset viewport). Without a viewport, fall back
|
|
549
|
+
// to the device config logical dimensions — this matches how the Studio
|
|
550
|
+
// client renders frameless browsers, and is identical to the viewport path
|
|
551
|
+
// for captures taken at the device's default viewport (logical − safe areas,
|
|
552
|
+
// see resolveDeviceViewport in capture-request-plan.ts).
|
|
532
553
|
// Safari uses a 52px visible toolbar (cropped from the 88px asset);
|
|
533
554
|
// Chrome uses a two-row 86px toolbar.
|
|
534
555
|
const BROWSER_BAR_HEIGHT = resolved.browserStyle === 'safari' ? 52 : 86;
|
|
@@ -539,11 +560,20 @@ export async function applyDeviceFrame(screenshot, deviceId, options) {
|
|
|
539
560
|
const safeAreaTop = normalizeBrowserSafeAreaTop(resolved.safeArea.top, 1, // logical pixels — pixelScale (os) handles final scaling
|
|
540
561
|
BROWSER_BAR_HEIGHT);
|
|
541
562
|
resolved.safeArea = { ...resolved.safeArea, top: safeAreaTop };
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
563
|
+
const captureViewport = sanitizeMockupViewport(opts.viewport);
|
|
564
|
+
if (captureViewport) {
|
|
565
|
+
geo.frameWidth = captureViewport.width
|
|
566
|
+
+ ((resolved.safeArea.left ?? 0) + (resolved.safeArea.right ?? 0)) * scale;
|
|
567
|
+
geo.frameHeight = captureViewport.height
|
|
568
|
+
+ (safeAreaTop + (resolved.safeArea.bottom ?? 0)) * scale;
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
// Frame = device config logical dimensions (not screenshot dimensions)
|
|
572
|
+
geo.frameWidth = logicalW;
|
|
573
|
+
geo.frameHeight = logicalH;
|
|
574
|
+
}
|
|
575
|
+
geo.screenRect = { x: 0, y: 0, width: geo.frameWidth, height: geo.frameHeight };
|
|
576
|
+
logger.debug(`[mockup] frameless browser: logicalW=${logicalW}, logicalH=${logicalH}, viewport=${captureViewport ? `${captureViewport.width}x${captureViewport.height}` : 'none'}, os=${os}, geo=${geo.frameWidth}x${geo.frameHeight}`);
|
|
547
577
|
}
|
|
548
578
|
else if (!hasFrame && geo.frameWidth === 0 && geo.frameHeight === 0) {
|
|
549
579
|
// Non-browser frameless fallback
|
|
Binary file
|