@littlepartytime/dev-kit 1.18.1 → 1.18.2
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.
|
@@ -11,67 +11,48 @@ const CAPTURE_H = 751; // 844 - 59 - 34
|
|
|
11
11
|
* Also exposed on window.__devkit__.captureScreen() for LLM/Playwright callers:
|
|
12
12
|
* await page.evaluate(() => window.__devkit__.captureScreen())
|
|
13
13
|
*
|
|
14
|
-
* ## Why
|
|
15
|
-
*
|
|
14
|
+
* ## Why onclone?
|
|
15
|
+
* html2canvas clones the entire document before rendering. The PhoneFrame DOM
|
|
16
|
+
* has three CSS properties that break the capture:
|
|
16
17
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
18
|
+
* - `contain: paint` on Screen div and safe-area div — html2canvas uses
|
|
19
|
+
* getBoundingClientRect() to compute clip rects, which returns the *visual*
|
|
20
|
+
* (post-transform) size, clipping the output to ~half height.
|
|
21
|
+
* - `transform: scale(x)` on the phone body — same getBoundingClientRect
|
|
22
|
+
* mismatch; intrinsic size is 390×751 but visual rect is smaller.
|
|
23
|
+
* - `overflow: hidden` on ancestors — once transform is removed, the full-size
|
|
24
|
+
* phone body overflows its scaled wrapper and gets clipped.
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* Fix: temporarily set both to neutral values, wait two rAF ticks for the browser to
|
|
28
|
-
* apply the changes, run html2canvas, then restore. An invisible overlay prevents the
|
|
29
|
-
* user from seeing the brief layout shift.
|
|
26
|
+
* Fix: in the `onclone` callback, neutralise all three properties on ancestor
|
|
27
|
+
* elements of the *cloned* document. The original DOM is never touched.
|
|
30
28
|
*/
|
|
31
29
|
export async function captureScreen(): Promise<string> {
|
|
32
30
|
const el = document.getElementById('devkit-game-screen');
|
|
33
31
|
if (!el) throw new Error('[devkit] #devkit-game-screen not found — is the Preview page active?');
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
const canvas = await html2canvas(el, {
|
|
34
|
+
width: CAPTURE_W,
|
|
35
|
+
height: CAPTURE_H,
|
|
36
|
+
scale: 2,
|
|
37
|
+
logging: false,
|
|
38
|
+
backgroundColor: null,
|
|
39
|
+
useCORS: true,
|
|
40
|
+
allowTaint: true,
|
|
41
|
+
onclone: (clonedDoc: Document) => {
|
|
42
|
+
const clonedEl = clonedDoc.getElementById('devkit-game-screen');
|
|
43
|
+
if (!clonedEl) return;
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
saved.push([node, prop, node.style[prop]]);
|
|
50
|
-
node.style[prop] = prop === 'transform' ? 'none' : '';
|
|
45
|
+
let node: HTMLElement | null = clonedEl;
|
|
46
|
+
while (node && node !== clonedDoc.body) {
|
|
47
|
+
node.style.contain = '';
|
|
48
|
+
node.style.transform = 'none';
|
|
49
|
+
node.style.overflow = 'visible';
|
|
50
|
+
node = node.parentElement;
|
|
51
51
|
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Wait for the browser to reflow/repaint with the normalised styles.
|
|
57
|
-
await new Promise<void>(r => requestAnimationFrame(() => requestAnimationFrame(r)));
|
|
52
|
+
},
|
|
53
|
+
});
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
const canvas = await html2canvas(el, {
|
|
61
|
-
width: CAPTURE_W,
|
|
62
|
-
height: CAPTURE_H,
|
|
63
|
-
scale: 2,
|
|
64
|
-
logging: false,
|
|
65
|
-
backgroundColor: null,
|
|
66
|
-
useCORS: true,
|
|
67
|
-
allowTaint: true,
|
|
68
|
-
});
|
|
69
|
-
return canvas.toDataURL('image/png');
|
|
70
|
-
} finally {
|
|
71
|
-
// Restore styles and remove overlay regardless of success/failure.
|
|
72
|
-
for (const [node, prop, val] of saved) node.style[prop] = val;
|
|
73
|
-
document.body.removeChild(overlay);
|
|
74
|
-
}
|
|
55
|
+
return canvas.toDataURL('image/png');
|
|
75
56
|
}
|
|
76
57
|
|
|
77
58
|
export function downloadScreenshot(dataUrl: string): void {
|