
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, andsetIntervalat the global level. Any animation that derives timing from these sources is automatically affected. - Web Animations API: Polls
document.getAnimations()every frame and adjustsplaybackRateon all liveAnimationobjects. This covers CSS@keyframes, CSS transitions, andelement.animate(). - Media element control: Sets
playbackRateon 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-excludeto 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 Type | Mechanism Used |
|---|---|
| CSS Animations | Web Animations API playbackRate |
| CSS Transitions | Web Animations API playbackRate |
| Video & Audio | HTMLMediaElement.playbackRate |
requestAnimationFrame loops |
Patched timestamps |
performance.now() |
Returns virtual time |
Date.now() |
Returns virtual epoch time |
setTimeout / setInterval |
Delays scaled by inverse of speed |
| GSAP | globalTimeline.timeScale() (auto-detected) |
| Three.js | Uses rAF — works automatically |
| Framer Motion / Motion | Uses Date.now() — works automatically |
| Canvas animations | Uses 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.
The post Pause, Slow, or Speed Up Web Animations – Slowmo appeared first on CSS Script.
Discover more from RSS Feeds Cloud
Subscribe to get the latest posts sent to your email.
