Capturing Dynamic UI Flows Without Manual Screen Recording
Static screenshots miss critical dynamic context when documenting long landing pages, reviewing front-end visual regressions across deployments, or building automated visual site tours. Recording screen captures manually for every pull request or site audit introduces variable scroll speeds, inconsistent mouse movements, and non-standard browser viewports.
Automating this process requires a rendering engine that opens a browser, standardizes the viewport, handles asynchronous elements like sticky navigation bars and cookie compliance popups, and captures frame-by-frame steps as the page scrolls down. The GIF Scroll Animation Actor automates this pipeline by running headless Chromium, capturing screenshots at deterministic pixel intervals, and assembling the frames into an optimized GIF file using Python's Pillow library.
How the Frame-by-Frame Capture Pipeline Operates
The capture process follows a sequential workflow designed to deliver repeatable frame pacing and consistent visual output:
-
Browser Initialization: Headless Chromium launches at the configured
viewportWidthandviewportHeight(defaulting to 1280x720 pixels). -
DOM and Consent Handling: The actor navigates to the target
urland waits fornetworkidle. If configured,waitToLoadPageMspauses execution for extra milliseconds to let lazy-loaded images, canvas animations, or web fonts render. IfcookieWindowSelectoris defined (such asbutton#accept-all), the browser clicks the element to clear overlay banners before frame capture starts. -
Incremental Scroll and Capture: The browser scrolls down by
scrollStepPxincrements (defaulting to 250 pixels). After each step, a frame is captured. This continues until the browser reaches the bottom of the page (scrollY + viewportHeight >= scrollHeight) or hits the definedmaxFrameshard cap. -
Processing and Encoding: Each frame screenshot is downscaled by
downscaleFactorto reduce final file size. Pillow quantizes the color palette and encodes the image array into a single animated GIF binary usingframeDelayMsto define the delay between frames. -
Storage and Output: The raw GIF binary is stored under the key
output.gifin the run's default key-value store. A companion metadata record is pushed to the run's default dataset.
JSON Input Configuration
You pass input parameters to control rendering resolution, scroll fidelity, and runtime caps. The example configuration below targets a landing page with quarter-resolution downscaling and explicit frame limits:
{
"url": "https://apify.com",
"viewportWidth": 1280,
"viewportHeight": 720,
"scrollStepPx": 250,
"frameDelayMs": 200,
"maxFrames": 40,
"downscaleFactor": 2,
"cookieWindowSelector": "button#onetrust-accept-btn-handler",
"waitToLoadPageMs": 1000
}
Dataset Output Record
When the execution finishes, the actor outputs a single dataset record containing spatial properties, durations, and direct storage keys:
{
"url": "https://apify.com",
"gifUrl": "https://api.apify.com/v2/key-value-stores/a1b2c3d4e5/records/output.gif",
"frameCount": 28,
"width": 640,
"height": 360,
"aspectRatio": 1.778,
"fileSizeBytes": 482113,
"frameDelayMs": 200,
"durationMs": 5600,
"scrapedAt": "2026-04-26T14:23:11+00:00"
}
How to Run the Actor via the Apify API
You can trigger this actor programmatically from Python, Node.js, or cURL. Follow these steps to generate a GIF scroll animation via the HTTP API:
- Construct the API Request: Send a POST request to the actor's run endpoint using your Apify API token.
-
Pass execution parameters: Supply the required target
urlalong with your desired viewport dimensions and frame configuration in the request payload. -
Poll or fetch the dataset item: Once the run status changes to
SUCCEEDED, read the output dataset item to extract thegifUrl.
import requests
APIFY_TOKEN = "your_apify_token_here"
ACTOR_ID = "crawlerbros~gif-scroll-animation"
run_input = {
"url": "https://apify.com",
"viewportWidth": 1280,
"viewportHeight": 720,
"scrollStepPx": 200,
"frameDelayMs": 150,
"maxFrames": 50,
"downscaleFactor": 2
}
url = f"https://api.apify.com/v2/acts/{ACTOR_ID}/runs?token={APIFY_TOKEN}"
response = requests.post(url, json=run_input)
run_data = response.json()["data"]
print(f"Run started with ID: {run_data['id']}")
To retrieve the raw binary without parsing dataset JSON, construct the Direct Key-Value Store URL using the store ID returned by the API:
https://api.apify.com/v2/key-value-stores/<KVS_ID>/records/output.gif
Managing File Size, Frame Rates, and Execution Costs
Animated GIFs do not use inter-frame compression like modern video codecs (e.g., H.264 or VP9). Capturing dozens of full-resolution frames can result in heavy output files exceeding 10 MB.
Three main settings control the balance between smoothness and final output size:
-
scrollStepPx: A smaller value (e.g.,50) produces smoother scrolling motion but generates significantly more total frames. -
downscaleFactor: An integer factor used by Pillow to resize frames prior to compilation. A factor of1preserves native full resolution, whereas a factor of2cuts frame width and height in half (reducing pixel count per frame by 75%). -
maxFrames: Caps the frame total regardless of total page length. If a target page uses infinite scroll or extensive vertical layouts, this setting prevents runaway execution.
Cost Breakdown
The pricing model for the Actor is structured as PAY_PER_EVENT, alongside separate charges for platform usage based on your plan's standard rates:
- Actor Start Event: Charged at $0.005 per GB of memory allocated to the run when execution begins.
-
Dataset Result Event: Charged at $0.002 per dataset item emitted (the single output record containing
gifUrland run metadata).
Discount tiers apply to the "result" event depending on your account tier: FREE ($0.002), BRONZE ($0.00167), SILVER ($0.00133), GOLD ($0.001), PLATINUM ($0.001), and DIAMOND ($0.001).
Operational Limits and Error Modes
If a page implements strict bot challenge barriers or blocks headless Chromium instances, the actor will emit a error record containing {type: "gif_scroll_error", reason: "capture_failed"} rather than crashing unhandled.
Note that this tool is designed exclusively for step-based screenshot stitching into rasterized animated GIFs; it does not capture native browser audio, encode MP4/WebM video formats, or support fluid variable-rate motion graphics capture for high-frame-rate web applications.
Source for the runs in this article: GIF Scroll Animation. The input schema there is authoritative; treat anything in this post that contradicts it as out of date.
Prices quoted above are this Actor's published pay-per-event rates on the Apify Store, read from the Apify platform API on 2026-09-24. Check the Actor page for the current rates.
Top comments (0)