@t3lnet/sceneforge 1.0.21 → 1.0.22

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.
@@ -212,33 +212,19 @@ export async function runRecordDemoCommand(argv) {
212
212
  await ensureDir(outputPaths.outputDir);
213
213
  await ensureDir(outputPaths.videosDir);
214
214
 
215
- const requestedViewport = parseViewportArgs(args, getFlagValue);
215
+ const viewport = parseViewportArgs(args, getFlagValue);
216
216
  const zoomFactor = parseDeviceScaleFactor(args, getFlagValue);
217
217
 
218
- // To achieve "zoom", we use a smaller viewport but record at the requested resolution.
219
- // This makes content appear larger (zoomed in) in the final video.
220
- // Example: --viewport 1080p --zoom 150 means:
221
- // - User wants 1920x1080 output video
222
- // - Content should appear 1.5x larger (zoomed)
223
- // - So we set viewport to 1280x720 (1920/1.5 x 1080/1.5)
224
- // - Record at 1920x1080
225
- const viewport = zoomFactor !== 1
226
- ? {
227
- width: Math.round(requestedViewport.width / zoomFactor),
228
- height: Math.round(requestedViewport.height / zoomFactor),
229
- }
230
- : requestedViewport;
231
-
232
- // Recording size is the requested viewport (the final video dimensions)
233
- const recordVideoSize = {
234
- width: requestedViewport.width,
235
- height: requestedViewport.height,
236
- };
218
+ // To achieve "zoom", we use CSS zoom to make content appear larger.
219
+ // The viewport stays at the requested size, and we inject CSS zoom after page load.
220
+ // Example: --viewport 4k --zoom 200 means:
221
+ // - Viewport is 3840x2160 (4K)
222
+ // - CSS zoom: 2 makes content appear 2x larger
223
+ // - User sees the equivalent of 1920x1080 content filling the 4K frame
237
224
 
238
225
  // Log what's happening
239
226
  if (zoomFactor !== 1) {
240
- console.log(`[record] Viewport: ${viewport.width}x${viewport.height} (zoomed ${Math.round(zoomFactor * 100)}%)`);
241
- console.log(`[record] Output video: ${recordVideoSize.width}x${recordVideoSize.height}`);
227
+ console.log(`[record] Viewport: ${viewport.width}x${viewport.height} with ${Math.round(zoomFactor * 100)}% CSS zoom`);
242
228
  } else {
243
229
  console.log(`[record] Viewport: ${viewport.width}x${viewport.height}`);
244
230
  }
@@ -255,9 +241,7 @@ export async function runRecordDemoCommand(argv) {
255
241
 
256
242
  const context = await browser.newContext({
257
243
  viewport,
258
- // Note: we achieve "zoom" by using a smaller viewport, not deviceScaleFactor
259
- // deviceScaleFactor only affects pixel density, not content size
260
- recordVideo: noVideo ? undefined : { dir: recordDir, size: recordVideoSize },
244
+ recordVideo: noVideo ? undefined : { dir: recordDir, size: viewport },
261
245
  storageState: storageState ? toAbsolute(rootDir, storageState) : undefined,
262
246
  locale: locale || undefined,
263
247
  extraHTTPHeaders: locale
@@ -268,12 +252,32 @@ export async function runRecordDemoCommand(argv) {
268
252
  });
269
253
 
270
254
  const page = await context.newPage();
255
+
256
+ // Apply CSS zoom if requested (must be done before navigation to affect all content)
257
+ if (zoomFactor !== 1) {
258
+ await page.addInitScript((zoom) => {
259
+ document.addEventListener('DOMContentLoaded', () => {
260
+ document.documentElement.style.zoom = String(zoom);
261
+ });
262
+ // Also set immediately in case DOMContentLoaded already fired
263
+ if (document.documentElement) {
264
+ document.documentElement.style.zoom = String(zoom);
265
+ }
266
+ }, zoomFactor);
267
+ }
268
+
271
269
  const video = page.video();
272
270
  const videoRecordingStartTime = Date.now();
273
271
  const startUrl = resolveStartUrl(startPath, baseUrl);
274
272
 
275
273
  if (startUrl) {
276
274
  await page.goto(startUrl, { waitUntil: "networkidle" });
275
+ // Ensure zoom is applied after navigation
276
+ if (zoomFactor !== 1) {
277
+ await page.evaluate((zoom) => {
278
+ document.documentElement.style.zoom = String(zoom);
279
+ }, zoomFactor);
280
+ }
277
281
  }
278
282
  const result = await runDemo(
279
283
  definition,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t3lnet/sceneforge",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "SceneForge runner and generation utilities for YAML-driven demos",
5
5
  "license": "MIT",
6
6
  "author": "T3LNET",