Auto Zoom
Automatically zoom into user actions with smooth easing transitions.
The .autoZoom() stage detects user interactions from the Playwright trace and zooms into the relevant UI area. The viewer's attention is drawn to exactly where the action happens.
Basic usage
await Recast
.from('./traces')
.parse()
.autoZoom()
.render({ format: 'mp4' })
.toFile('demo.mp4')Auto-zoom from trace
Automatically zoom into input elements (fill/type actions) detected from the trace. The zoom window follows the actual action duration — zooms in when the user starts typing, zooms out when they move on.
.autoZoom({
inputLevel: 1.4, // Zoom level for fill/type actions
clickLevel: 1.0, // 1.0 = no zoom on clicks (default)
centerBias: 0.3, // Blend coordinates toward center (0-1)
})Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
inputLevel | number | 1.4 | Zoom level for fill/type actions |
clickLevel | number | 1.0 | Zoom level for click actions |
idleLevel | number | 1.0 | Zoom level when no action is happening |
centerBias | number | 0 | Blend zoom coordinates toward viewport center (0-1) |
easing | EasingSpec | 'ease-in-out' | Easing function for zoom transitions |
transitionMs | number | 400 | Zoom in/out transition duration in ms |
Easing options
Zoom transitions support several easing modes:
// Built-in presets
.autoZoom({ easing: 'linear' })
.autoZoom({ easing: 'ease-in' })
.autoZoom({ easing: 'ease-out' })
.autoZoom({ easing: 'ease-in-out' }) // default
// Cubic bezier
.autoZoom({ easing: { cubicBezier: [0.42, 0, 0.58, 1] } })
// Custom JS function
.autoZoom({ easing: { fn: t => t * t } })Zoom-to-zoom panning
When two zoom targets are close together in time, the camera pans smoothly between them instead of zooming out and back in. This creates a natural follow-along feel.
Zoom from report data
Apply zoom coordinates from an external source:
const reportSteps = [
{ zoom: null }, // Step 1: no zoom
{ zoom: { x: 0.5, y: 0.8, level: 1.4 } }, // Step 2: zoom to input area
{ zoom: null }, // Step 3: no zoom
{ zoom: { x: 0.78, y: 0.45, level: 1.3 } }, // Step 4: zoom to sidebar
]
await Recast
.from('./traces')
.parse()
.subtitlesFromSrt('./narration.srt')
.enrichZoomFromReport(reportSteps)
.render({ format: 'mp4' })
.toFile('demo.mp4')Zoom from step helpers
Capture zoom coordinates during test execution using the zoom() helper:
import { zoom } from 'playwright-recast'
When('the user opens the sidebar', async ({ page }) => {
const sidebar = page.locator('.sidebar-panel')
await zoom(sidebar, 1.3)
await sidebar.click()
})The helper records the element's bounding box as a Playwright annotation. Apply these coordinates with .enrichZoomFromReport().
Zoom coordinates
All zoom coordinates use viewport-relative fractions (0.0-1.0):
| Field | Description | Default |
|---|---|---|
x | Center X (0 = left, 1 = right) | 0.5 |
y | Center Y (0 = top, 1 = bottom) | 0.5 |
level | Zoom level (1.0 = no zoom, 2.0 = 2x) | 1.0 |
The renderer applies zoom by cropping the video to (width/level x height/level) centered at (x, y), then scaling back to the output resolution.
Tips
- Use
centerBiasto prevent zoom targets near edges from cropping important content. A value of0.3blends 30% toward the center. - Cursor overlay and click effects are applied before zoom cropping, so overlay coordinates stay accurate during zoomed segments.
- For fill actions that lack cursor coordinates (programmatic fills), auto-zoom falls back to viewport center.