Smooth Scroll

DXRK1E
2024-07-23T23:57:47Z

Configurable smooth scroll with optional motion blur. Uses requestAnimationFrame (like V-Sync).

Smooth Scroll UserScript: The Lowdown

So, you've got this JavaScript UserScript. What's the deal with it?

What is it? (The Elevator Pitch)

Basically, it's a browser script that hijacks the normal mouse wheel scrolling and replaces it with a super smooth, customizable, animated scroll. Think macOS trackpad scrolling or smooth scrolling in some native apps, but potentially everywhere you browse. It aims to make scrolling webpages feel less jerky and more fluid.

What does it actually do?

1. Listens for Scroll Events: It attaches itself to wheel events on the page.

2. Finds the Right Target: When you scroll your wheel, it's smart enough to figure out what you're trying to scroll. Is it the whole page? Or just that little box with overflow: scroll;? It checks the element under your mouse and its parents to find the correct scrollable container.

3. Prevents Default Jank: It stops the browser's default "jump scroll" behavior (e.preventDefault()).

4. Calculates the Destination: Based on your wheel input (how much you scrolled, and if it was lines or pixels), it calculates a target Y scroll position.

5. Animates Smoothly: This is the core magic. Instead of jumping, it uses requestAnimationFrame (which syncs with your screen's refresh rate, like V-Sync in games) to smoothly transition the scrollTop of the target element from its current position to the target Y.

6. Applies Physics (Sorta): It uses a damping factor (cfg.smth) to make the scroll ease out naturally, not just stop abruptly. It also has a simple acceleration mechanic (cfg.accDelFct, cfg.accMaxMult) – if you scroll the wheel repeatedly and quickly, it scrolls further per tick, making fast scrolling feel more responsive.

7. Optional Eye Candy (Motion Blur): If cfg.mBlur is true, it applies a CSS filter: blur(...) effect to the scrolling element. The faster the scroll, the stronger the blur (up to a limit). Makes it look dynamic, but can impact performance slightly on lower-end machines.

8. Stops Nicely: It stops the animation when the scroll position is very close to the target (cfg.thrsh), or if you interrupt it by clicking or touching the screen (_hdlClick).

9. Configurable: You can tweak settings like smoothness, step size, acceleration, and motion blur right at the top in the cfg object.

How it Works (The Simple Tech Bits)

requestAnimationFrame Loop (_animStep): The heart of the smoothness. It runs every frame, calculating a small step towards the target scroll position based on the remaining distance and the DAMP_FCT (derived from cfg.smth). It then updates the element's scrollTop.

State Management (stMap): Uses a WeakMap to keep track of the animation state (target position, current animated position, animation ID, etc.) for each element being scrolled. WeakMap is good because it doesn't prevent elements from being garbage-collected if they're removed from the page.

Event Handling (_hdlWheel, _hdlClick): Captures mouse wheel events globally (capture: true) to intercept them early. Also listens for clicks/touches to cancel ongoing scrolls.

Helper Functions: Lots of small functions (_getScrTop, _setScrTop, _isScr, _getTgt, etc.) to handle the details cleanly, like getting/setting scroll positions correctly for both the main window and specific elements, checking if an element is actually scrollable, and converting wheel delta modes to pixels.

Is it Safe to Use?

Permissions: Yes, generally safe. It uses @grant none, meaning it doesn't require any special, potentially risky browser API access provided by UserScript managers like Tampermonkey. It just manipulates standard DOM properties (scrollTop, style.filter, style.scrollBehavior).

Scope: It runs on all websites (@include *). This is convenient but means it might potentially conflict with websites that have their own very complex, custom scrolling JavaScript. Usually, it's fine, but keep an eye out. The script tries to avoid conflicts by temporarily setting scroll-behavior: auto on the element it's animating.

Performance: requestAnimationFrame is very efficient for animations. The main potential performance hit is the optional motion blur, especially on complex pages or older hardware. If scrolling feels laggy, try setting cfg.mBlur = false;. Without the blur, it should be quite lightweight.

Code Quality: The code looks reasonably clean and uses modern practices (like WeakMap, const/let, IIFE scope). The document-start run time means it loads early to catch scroll events reliably.

In Short (TL;DR):

It's a well-written UserScript to give you configurable, physics-based smooth scrolling across websites. It uses efficient animation techniques (requestAnimationFrame) and includes optional motion blur. It's generally safe to use as it doesn't need special permissions, but the motion blur might impact performance, and it could clash with the odd website that does super fancy scrolling things itself. If you like smooth scrolling, give it a whirl and tweak the cfg to your liking!