Recommended Free Tools
Chromatic already pauses CSS transitions and CSS/SVG animations. For CSS animations, it captures the last frame by default; set chromatic.pauseAnimationAtEnd: false when the starting frame is the intended reference. JavaScript-driven animations need a separate fix: disable them in visual-test runs or make the test wait for a verified stable state.
First identify what is moving
The right fix depends on whether the changing pixels come from CSS, JavaScript, or animated media. Chromatic’s animation guidance describes different capture behavior for each, so start by identifying the mechanism rather than adding a delay to every story. See Chromatic’s animation documentation.
As an Amazon Associate I earn from qualifying purchases.
- CSS transitions and CSS/SVG animations: Chromatic pauses these automatically.
- JavaScript animation libraries: Chromatic does not disable them automatically. Configure the library for visual tests or synchronize capture with the intended state.
- GIFs and videos: Chromatic pauses animated GIFs and videos at their first frame. If a video has a
poster, Chromatic uses that image.
Animation can still be the intended behavior under test. In that case, do not suppress or omit it; instead, make the test capture a deliberate state.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choose the intended frame for CSS animation
Chromatic’s default CSS animation behavior pauses at the end of the animation cycle, which is often appropriate for an entrance animation whose completed appearance is the expected snapshot. To capture the starting frame instead, set pauseAnimationAtEnd: false.
#1 Best Overall
For Storybook, configure the chromatic parameter at the narrowest useful scope: on an individual story, a component’s meta, or project-wide in Storybook parameters. For example, at story scope:
export const MyStory = {
parameters: {
chromatic: { pauseAnimationAtEnd: false },
},
};
Use this only where the first frame is the correct reference. A project-wide setting changes the frame choice for all affected stories. Chromatic says this option became enabled by default with Capture Stack version 6 general availability in February 2024; projects that adopted that behavior may therefore differ from older captures. Check the Storybook parameters and globals reference for supported configuration and scope.
Make JavaScript animation deterministic
Disable motion in visual-test runs when animation is not under test
If a story uses Framer Motion 10.17.0 or newer, Chromatic documents using isChromatic() to detect a Chromatic run and set Framer Motion’s MotionGlobalConfig.skipAnimations. Follow the current integration guidance for the exact import and setup in your project, and apply the setting only in the visual-testing environment if normal user-facing motion should remain unchanged.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
Other JavaScript animation libraries have their own controls; use the library’s supported test or reduced-motion configuration rather than assuming Chromatic will pause its timers or animation loop.
Wait for a meaningful completed state
If the animation represents behavior the story is testing, let it run and assert that its result is ready before capture. In a Storybook interaction test, Chromatic waits for the story’s play function to finish, including its interactions, assertions, and delays. A state assertion in that function can therefore gate the snapshot:
export const OpensPanel = {
play: async ({ canvas, userEvent }) => {
await userEvent.click(canvas.getByRole('button', { name: 'Open panel' }));
await expect(canvas.getByRole('region', { name: 'Details' })).toBeVisible();
},
};
Use the assertion that represents the behavior you need—for example, an element becoming visible or a completion marker appearing—rather than treating elapsed time alone as proof that the right state has been reached. Chromatic’s snapshot documentation explains capture timing and interaction tests.
Rank #3
Use waits and capture options for the problem they solve
chromatic.delay: waits for a specified time before capture. It can help when no reliable condition is available, but it remains time-based; choose a duration based on the actual animation and runtime, not as a universal value.chromatic.prefersReducedMotion: changes the reduced-motion preference for the capture. Use it when the story is meant to render its reduced-motion state; it is not a general guarantee that every JavaScript animation will stop.chromatic.ignoreSelectors: excludes matching regions from visual comparison. Use it only when those pixels are not part of what the story is supposed to verify.
These settings solve different problems: waiting gives an animation time to reach a state, reduced motion changes a browser preference, and ignored selectors remove pixels from comparison. See the parameter reference for supported Storybook parameters.
Why network idle does not necessarily mean animation complete
Chromatic uses network quiescence in part as a signal that page resources have loaded. Network inactivity does not guarantee that JavaScript-driven motion has finished. If capture timing matters, establish readiness with a condition, an explicit completion marker, or the end of the Storybook play function rather than relying on network idle alone.
Disable snapshots only when capture itself is unwanted
chromatic.disableSnapshot can disable a Storybook snapshot at story, component, or project level. For Vitest, Playwright, and Cypress integrations, disableAutoSnapshot disables the default end-of-test snapshot when you are taking targeted snapshots instead. These controls suppress capture; they do not make an animation deterministic. Use them when a default snapshot is not wanted, not as a substitute for testing a stable state. See Chromatic’s snapshot-disabling guidance.
Troubleshoot changing snapshots
The animated element is CSS-based but snapshots still differ
Confirm that the motion is actually CSS animation, transition, or CSS/SVG animation rather than being driven by JavaScript. Then decide whether the first or last frame is correct and set pauseAnimationAtEnd only if the default final frame is not the intended state. Check whether the animation’s changing output is genuinely part of the visual requirement.
A JavaScript animation is caught mid-motion
Chromatic does not automatically disable JavaScript-driven animation. Turn it off for visual-test runs where motion is irrelevant, or wait for an observable final state before the snapshot. A delay may mask the symptom but can remain unreliable if runtime or animation duration varies.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →A video or GIF differs from the expected CSS behavior
Media uses separate behavior: Chromatic pauses animated GIFs and videos at the first frame, and uses a video’s poster when available. Do not expect the CSS animation last-frame setting to select a video’s frame.
Best Value
An older project captures a different CSS frame
Review when the project adopted Chromatic’s Capture Stack behavior. The animation guide says pauseAnimationAtEnd became enabled by default with Capture Stack version 6 general availability in February 2024. If the intended baseline is the starting frame, set the option to false at the appropriate scope.
Or skip the browser setup
For a standalone website screenshot rather than a Chromatic Storybook snapshot, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed; and AI agents can use its MCP server to take screenshots. It includes 1,000 screenshots per month free with no card, and paid plans start at $5 for 3,000.
For API details and options, see the ScreenshotNeo documentation. cURL example:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Sign up for 1,000 free screenshots a month, with no card required.
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.




