GIF Scroll Animation avatar

GIF Scroll Animation

Pricing

from $1.00 / 1,000 results

Go to Apify Store
GIF Scroll Animation

GIF Scroll Animation

Generate an animated GIF that scrolls down a webpage.

Pricing

from $1.00 / 1,000 results

Rating

5.0

(10)

Developer

Crawler Bros

Crawler Bros

Maintained by Community

Actor stats

8

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Generate an animated GIF that scrolls down a webpage. The actor opens the URL in a headless Chromium browser, captures one frame per scroll step, then assembles the frames into a GIF using Pillow. The GIF is saved to the run's key-value store; a companion record with metadata + a public GIF URL is pushed to the dataset.

What it does

You provide a webpage URL; the actor:

  1. Renders the page in headless Chromium at the configured viewport size.
  2. Scrolls the page in scrollStepPx-sized increments, capturing a screenshot per step (up to maxFrames).
  3. Optionally downscales each frame, then encodes them as a single GIF with Pillow.
  4. Writes the GIF binary to the key-value store under output.gif.
  5. Pushes one dataset record with {url, gifUrl, frameCount, width, height, fileSizeBytes, frameDelayMs, scrapedAt}.

Input

FieldTypeDefaultDescription
urlstring (required)https://apify.comPage to capture. Must start with http:// or https://.
viewportWidthinteger1280 (320–2560)Browser viewport width in pixels.
viewportHeightinteger720 (240–1440)Browser viewport height in pixels.
scrollStepPxinteger250 (50–2000)Pixels to scroll between captured frames. Smaller values → smoother animation but more frames.
frameDelayMsinteger200 (50–5000)Per-frame delay encoded into the GIF.
maxFramesinteger60 (2–300)Hard cap on captured frames so very tall pages don't run forever.
downscaleFactorinteger2 (1–8)Resize each frame down by this integer factor before encoding. 1 = full resolution, 2 = half, 4 = quarter. Lower = sharper but bigger GIF.
cookieWindowSelectorstring (optional)CSS selector of a cookie-consent dismiss button (e.g. button#accept-all). Clicked after page load so the consent banner doesn't appear in every frame.
waitToLoadPageMsinteger0 (0–30000)Extra wait (ms) after networkidle for async-loaded content (lazy images, animations) to settle before capture starts.

Example input

{
"url": "https://apify.com",
"viewportWidth": 1280,
"viewportHeight": 720,
"scrollStepPx": 250,
"frameDelayMs": 200,
"maxFrames": 40,
"downscaleFactor": 2
}

Output

The dataset receives a single record per run:

{
"url": "https://apify.com",
"gifUrl": "https://api.apify.com/v2/key-value-stores/<kvs-id>/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"
}

The GIF binary itself is stored under key output.gif in the run's default key-value store and is reachable at the public gifUrl shown above.

Output fields

  • url — the source URL captured.
  • gifUrl — public URL pointing to the rendered GIF in the key-value store.
  • frameCount — how many frames were captured before reaching the bottom or maxFrames.
  • width / height — final GIF dimensions in pixels (after downscaleFactor).
  • aspectRatio — derived: width / height rounded to 3 decimal places.
  • fileSizeBytes — encoded GIF size in bytes.
  • frameDelayMs — per-frame delay used in the GIF.
  • durationMs — derived: frameDelayMs * frameCount — total GIF duration in milliseconds.
  • scrapedAt — ISO-8601 UTC timestamp.

Use cases

  • Marketing previews — generate a quick animated preview of a landing page for social media, slack messages, or PR demos.
  • Scroll-test recording — visualise long pages for accessibility / visual-regression review.
  • Documentation screenshots — capture a page-tour as a single embeddable GIF instead of multiple stills.
  • Visual diffs — re-run on the same URL across deploys to compare scroll appearance over time.

FAQ

Does it need a proxy? No — the actor uses the run's default network. If you need to capture a page that's geo- or IP-restricted, configure proxy at the run level via Apify's run-options panel.

How big can the GIF get? Pillow uses optimised palette quantisation and disposal=2 to keep frames small, but a 30-frame full-1280×720 capture is still ~8–12 MB. Use downscaleFactor: 2 (default) to roughly quarter the size.

Why does the GIF stop early?

  • Reached the bottom of the page (scrollY + viewportHeight >= scrollHeight).
  • Hit maxFrames. Increase the limit if you have a very tall page.

Why isn't it perfectly smooth? GIF can only encode 1×, 2×, 5×, 10× hundredths-of-a-second, and Pillow rounds to the nearest. For motion-graphics quality, render to MP4 instead (this actor doesn't do video).

How do I get just the GIF without the dataset record? Run the actor and download output.gif from the run's key-value store (the URL is in the dataset record's gifUrl).

The page didn't render — what happened? Some pages block headless Chromium with bot challenges. The actor emits a sentinel record {type: "gif_scroll_error", reason: "capture_failed", ...} rather than crashing. Try the page in a normal browser first to confirm it isn't paywalled or geo-blocked.