Pause, Slow, or Speed Up Web Animations – Slowmo

Category: Animation , Javascript | February 19, 2026
Authorseflless
Last UpdateFebruary 19, 2026
LicenseMIT
Tags
Views36 views
Pause, Slow, or Speed Up Web Animations – Slowmo

Most web animations are built on “vibes.” You tweak a cubic-bezier, refresh the browser, and hope it feels right. When it doesn’t, you’re stuck squinting at a 300ms transition that happens too fast to diagnose.

Meet slowmo, a JavaScript library that intercepts time at the browser level to slow down, pause, or accelerate every animation running on a page.

It patches requestAnimationFrame, performance.now(), Date.now(), and the Web Animations API simultaneously. This means CSS keyframe animations, CSS transitions, <video> and <audio> elements, canvas loops, and popular libraries like GSAP, Three.js, and Framer Motion all respond to a single speed multiplier.

Features:

  • Time patching: Patches requestAnimationFrame, performance.now(), Date.now(), setTimeout, and setInterval at the global level. Any animation that derives timing from these sources is automatically affected.
  • Web Animations API: Polls document.getAnimations() every frame and adjusts playbackRate on all live Animation objects. This covers CSS @keyframes, CSS transitions, and element.animate().
  • Media element control: Sets playbackRate on all <video> and <audio> elements.
  • GSAP auto-detection: Detects a loaded GSAP instance and calls gsap.globalTimeline.timeScale() natively, so GSAP animations stay perfectly in sync.
  • Opt-out mechanism: Add data-slowmo-exclude to any element to keep its animations running at normal speed regardless of the global setting.

See It In Action:

Use Cases:

  • Animation Debugging: Slow down complex UI transitions to 0.1x speed. This helps verify alignment and easing curves.
  • Accessibility Testing: Check how interfaces behave for users who prefer reduced motion or slower interaction rates.
  • Game Development: Implement “slow motion” or “pause” mechanics in browser-based games easily.
  • Motion Design Review: Review micro-interactions and hover effects in extreme detail

How To Use It:

1. Install slowmo with NPM.

# NPM
$ npm install slowmo

2. Import the library and call slowmo with a numeric speed multiplier. The library installs its patches automatically on import in any browser environment.

import slowmo from "slowmo";
// Set a specific speed multiplier (0 = pause, 1 = normal, 2 = double, etc.)
slowmo(0.5);
// Pause all animations — equivalent to slowmo(0)
slowmo.pause();
// Resume from the paused state. Resumes at the previously set speed,
// or 1× if no speed was set before pausing.
slowmo.play();
// Reset speed to 1× (normal)
slowmo.reset();
// Returns the current speed multiplier as a number
const currentSpeed = slowmo.getSpeed();
console.log(currentSpeed); // e.g., 0.5

3. Add the data-slowmo-exclude attribute to any HTML element to exempt its animations from global speed control. The library checks closest('[data-slowmo-exclude]') on each animation’s target element.

<!-- This element's animations run at normal speed regardless of the global slowmo setting -->
<div data-slowmo-exclude>
  <div class="loading-spinner"></div>
</div>
<!-- This element is affected by slowmo normally -->
<div class="hero-animation"></div>

4. Slowmo includes a visual dial. This lets you drag and rotate a UI widget to control time dynamically.

  • Center click: Toggles pause/play.
  • Middle ring drag: Repositions the dial on the screen.
  • Outer edge rotation: Changes speed. Uses the Pointer Lock API for smooth, unbounded rotation.
import { setupDial, shutdownDial } from "slowmo/dial";
// Mount the dial to the page. It is draggable and persists position in localStorage.
setupDial();
// Remove the dial and clean up all event listeners
shutdownDial();

What slowmo affects:

Animation TypeMechanism Used
CSS AnimationsWeb Animations API playbackRate
CSS TransitionsWeb Animations API playbackRate
Video & AudioHTMLMediaElement.playbackRate
requestAnimationFrame loopsPatched timestamps
performance.now()Returns virtual time
Date.now()Returns virtual epoch time
setTimeout / setIntervalDelays scaled by inverse of speed
GSAPglobalTimeline.timeScale() (auto-detected)
Three.jsUses rAF — works automatically
Framer Motion / MotionUses Date.now() — works automatically
Canvas animationsUses rAF — works automatically

FAQs:

Q: Does slowmo affect animations in third-party widgets or embedded components I didn’t write?
A: Yes, as long as the third-party code runs in the same browsing context and derives timing from requestAnimationFrame, performance.now(), or Date.now().

Q: My canvas animation doesn’t slow down. What’s wrong?
A: The most common cause is that the animation loop ignores the rAF timestamp parameter and uses a fixed increment per frame. Check your loop: if it reads (timestamp) => { x += 5; } and never uses timestamp, the patch has no effect.

Q: Can I use slowmo alongside GSAP on the same page?
A: Yes. slowmo auto-detects a loaded GSAP instance and calls gsap.globalTimeline.timeScale() whenever setSpeed() runs. Both GSAP animations and non-GSAP animations are controlled by the same slowmo() call. We tested this with GSAP 3.x and found no conflicts.

Q: What happens to setTimeout and setInterval calls when speed is set to 0?
A: The patched setTimeout and setInterval scale delays by the inverse of the current speed. At speed = 0, the effective delay becomes effectively infinite — callbacks do not fire. They resume when speed is set to a non-zero value. Note that any setTimeout calls made while paused will use the paused speed at the moment they were registered.

You Might Be Interested In:


Leave a Reply