Recommended Free Tools
Use page.render() only after the animation has had time to advance. For an approximate frame, wait with a timer after page.open() reports success. For repeatable screenshots, run page.evaluate() in the page context to put the animation or target element into a known state, then render. PhantomJS does not provide an animation-frame selector, and its project says development is suspended, so verify behavior on the exact PhantomJS/QtWebKit build you deploy.
What PhantomJS can—and cannot—capture
PhantomJS captures the page as it exists when page.render() executes. The normal load callback tells you that navigation completed; it does not mean a CSS animation has reached a particular keyframe. A delay therefore chooses an elapsed time, not a guaranteed frame.
The official documentation describes PhantomJS as a headless WebKit browser and notes that development is suspended until further notice (official PhantomJS homepage). CSS animation support can differ between builds. Do not assume that every modern animation property, timing function, or vendor prefix behaves identically in your runtime.
Choose a capture strategy
Approximate timing with a delay
Use a timer when “roughly one second after load” is good enough. It is simple, but the result can move between runs if fonts, images, network requests, JavaScript startup, or animation start time vary.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Set a known state before rendering
For regression images or documentation, use page.evaluate() to change styles or classes in the page itself, pause an animation, or set an explicit progress state. This is more repeatable than sleeping, but the code must match the page’s implementation and the behavior supported by your WebKit build.
Capture only the relevant region
Set viewportSize before navigation for a controlled layout. Set clipRect when the screenshot should contain only the animated component. The screen-capture guide documents both controls and the supported PNG, JPEG, GIF, and PDF outputs (Screen Capture with PhantomJS).
Minimal delayed screenshot
This complete script waits one second after a successful load, renders a PNG, and exits. The delay is an example starting point, not a universal value; tune it for the page you are capturing.
var page = require('webpage').create();
page.viewportSize = { width: 1024, height: 768 };
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.log('Unable to load page');
phantom.exit(1);
return;
}
// Approximate capture point; tune for the target animation.
setTimeout(function () {
page.render('capture.png');
phantom.exit();
}, 1000);
});
Run it with the PhantomJS executable, for example phantomjs capture.js. The quick-start documentation demonstrates the same load-then-render pattern and explains why phantom.exit() is needed to terminate the script (Quick Start).
Capture a selected animation state
A page-context function can alter the DOM or inline styles before the screenshot. The following example pauses an element and sets its animation delay to a chosen negative offset. Whether this produces the intended visual state depends on the page’s CSS and the PhantomJS build, so inspect the output rather than assuming modern browser behavior.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
var page = require('webpage').create();
page.viewportSize = { width: 1024, height: 768 };
page.open('https://example.com/animated-page', function (status) {
if (status !== 'success') {
console.log('Unable to load page');
phantom.exit(1);
return;
}
var changed = page.evaluate(function () {
var element = document.querySelector('.hero-animation');
if (!element) {
return { ok: false, reason: 'Target element not found' };
}
// These declarations are page-specific. Adjust the property names and
// values to the animation used by the target site.
element.style.webkitAnimationPlayState = 'paused';
element.style.animationPlayState = 'paused';
element.style.webkitAnimationDelay = '-1s';
element.style.animationDelay = '-1s';
return { ok: true };
});
if (!changed.ok) {
console.log(changed.reason);
phantom.exit(1);
return;
}
page.render('animation-state.png');
phantom.exit();
});
page.evaluate() executes in the web page context. Values crossing the boundary must be simple JSON-serializable data; closures, DOM nodes, and other complex objects cannot be returned directly. See the evaluate API documentation. Return a small status object, as above, rather than the element itself.
How to make repeated captures more consistent
Wait for prerequisites, not just a clock
A successful page.open() callback is a useful starting point, but external fonts, images, application data, and delayed JavaScript can still be loading. If the animation starts only after an application event, wait for a page-specific marker or use a conservative delay after that marker. PhantomJS’s page automation documentation lists callbacks such as onLoadFinished and onRepaintRequested, but neither callback selects a CSS animation frame (Page Automation).
Freeze the page before rendering
When possible, add a capture-only class or inline declarations that pause motion and select a known state. If the site exposes a progress class, set that class instead of guessing at elapsed milliseconds. Remove transitions from unrelated elements so a blinking cursor, carousel, or hover effect does not alter the image.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Control layout inputs
- Set
viewportSizebeforepage.open(). - Use the same URL, query parameters, cookies, and user agent on every run.
- Set
clipRectonly after confirming the element’s position at the chosen viewport. - Use a stable output format and render quality settings documented by the render API.
Check the actual output
Run several captures on the exact machine and PhantomJS binary. Compare pixels or inspect the animation region manually. If the image changes despite a controlled state, the cause may be an unsupported CSS feature, asynchronous application code, font substitution, or a resource that has not finished loading.
Full-page and clipped captures
For a viewport screenshot, omit clipRect. For a component, assign a rectangle in page coordinates:
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
page.clipRect = { top: 120, left: 80, width: 640, height: 360 };
page.render('component.png');
The rectangle is not a CSS selector; it is a coordinate region. If responsive layout changes the component’s position, calculate the rectangle in page.evaluate() and return only numeric coordinates, then assign it in PhantomJS. Keep the returned object JSON-serializable.
Troubleshooting PhantomJS animation screenshots
The screenshot is taken before the animation moves
Cause: rendering occurs immediately after load, or the animation starts after another script runs. Fix: add a measured delay after the real start event, or set the animation state in page.evaluate() before page.render().
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallEvery run shows a different frame
Cause: elapsed-time capture is sensitive to resource and JavaScript timing. Fix: pause the target, set a page-specific state, disable unrelated motion, and keep viewport and inputs identical. A timer alone cannot guarantee determinism.
The animation does not respond to the style change
Cause: the selector is wrong, the site uses a class or script to control state, or the legacy WebKit build does not implement the property as expected. Fix: return a “target not found” status, test the exact property in that build, and use the site’s own state class or DOM controls where available.
page.evaluate() returns an error or unusable value
Cause: the function tries to return a DOM node, closure, or another non-serializable value. Fix: return strings, numbers, booleans, arrays, or plain objects containing those types; perform DOM work inside the evaluated function.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
The page loads but the target is blank
Cause: a failed request, delayed data, blocked resource, or an animation dependent on unsupported browser behavior. Fix: log page errors and network failures in your script, wait for an application-ready marker, and verify the URL in the same PhantomJS build. If the required behavior cannot be made reliable, move the capture to a maintained browser automation runtime that supports the page’s CSS and JavaScript.
The script never exits
Cause: the timer or callback path does not call phantom.exit(). Fix: call it after both successful and failure paths, and only after rendering has completed.
Performance, reliability, and output choices
- Delay cost: every extra wait increases wall-clock time. Measure the target page’s asset and animation startup, then use the shortest delay that is reliable for your build.
- Repeatability: explicit page state is generally more stable than a timestamp, but it is coupled to the page’s CSS and JavaScript.
- Viewport versus clip: a smaller clip reduces the image area and makes comparisons easier; it does not fix an unstable animation.
- Format: PNG is suitable for pixel comparisons; JPEG trades fidelity for smaller files. The render API documents format and quality options.
- Maintenance risk: PhantomJS is suspended software. Pin the binary, record its version and operating environment, and re-check captures after page or dependency changes.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request captures a URL as PNG, JPEG, WebP, or PDF, with options for full-page output, viewport and device presets, retina scale, custom CSS and JavaScript, selector clipping, waits, and more. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.
For an animation, supply custom JavaScript or a wait condition that puts the page in the state you need. The API also supports caching with a chosen TTL, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, custom headers and cookies, geolocation and timezone, transparent backgrounds, and signed links for public image tags. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for parameters and response headers. The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try the capture without installing PhantomJS.
Frequently asked questions
Can PhantomJS export an animated GIF of the CSS animation?
The screen-capture guide lists GIF as an output format, but a single page.render() call captures one page state; it is not documented as a multi-frame animation recorder. Capture separate states and assemble them with a tool that supports GIF creation if you need a sequence.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Does onRepaintRequested provide the exact animation frame?
No. It is a repaint notification, not a frame-selection API. Use it for page automation signals only, and control the state explicitly when repeatability matters.
What if the site requires modern browser APIs?
PhantomJS uses legacy WebKit and its development is suspended. If the page depends on APIs or CSS behavior your build lacks, a maintained browser automation runtime is the practical fallback.
Can I use the same PhantomJS script for every animated site?
No. Selectors, animation implementation, loading triggers, and supported CSS differ by page and build. Treat the timer and state-setting code as page-specific capture logic.
Free tools Windows power users keep installed
One-click scans. No signup required.
Frequently Asked Questions
Is a one-second delay a reliable standard for CSS animations?
No. It is only an example starting point; tune the delay to the target page and runtime, or set a known state with page-context code.
Why does a successful page.open callback not identify an animation frame?
It reports navigation completion. It does not wait for fonts, application data, or a particular point in a CSS animation.
Where are PhantomJS’s documented viewport and clipping controls?
The screen-capture guide documents viewportSize and clipRect; use viewportSize before navigation and clipRect for a coordinate-based region.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems

