Universal Auto Scroll

Press Alt + X to start auto-scroll or increase speed. X to pause/resume, Space / Esc to stop. Use Up/Down to adjust speed. Page Up/Down work normally during scroll/pause. Mouse Up/Down pauses during scroll and work normally during pause.

// ==UserScript==
// @name           Universal Auto Scroll
// @version        2.0
// @namespace      MedX-AA
// @author         MedX
// @license        MIT
// @description    Press Alt + X to start auto-scroll or increase speed. X to pause/resume, Space / Esc to stop. Use Up/Down to adjust speed. Page Up/Down work normally during scroll/pause. Mouse Up/Down pauses during scroll and work normally during pause.
// @icon           data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABGUlEQVR4nO3VsS4EURQG4E9oRCEh0ZDQi3gDjV7lHXTeAYVo9gl0ahregEapoKEh0SFRbVbIyiSjEYnd2TtzZ5PzJSeZYjbzn/2LQwghlSN8oP/PFO8caqHeAOF/pni3dfpDTuvEArlFA7lFA7lFA7lFA7lFA7lFA7lFA7lFA7m1uoE9dCuErDrd8pvJvDYYvl/OS8oFOhkW6KRcYBKnDYY/x5TEpnHZQPhrzKjJLG5qDH+LOTVbxGMN4Z+xrCGreEsY/h3rGraR6Db0sCmTLXyOEP4L2zLbGWGBXS1xUCH8vhaZwPEQ4U/K37RKca3PBgh/UceVTXmtr3Jd2VTmcfdH+HssGBNLePp1ZVeMmTU8lP988RxCkN43yek7CExEuggAAAAASUVORK5CYII=
// @grant          none
// @include        *
// ==/UserScript==

// === CONFIGURATION ===
const INITIAL_SPEED = 30; // Pixels per second
const SPEED_MULTIPLIER = 2.0; // Speed increase factor
const SLOWDOWN_MULTIPLIER = 0.5; // Speed decrease factor

// === KEY BINDINGS ===
const START_KEY = 88; // Alt + X starts/increases speed
const PAUSE_KEY = 88; // X pauses/resumes (only while scrolling)
const STOP_KEYS = new Set([27, 32]); // Escape & Space both fully stop scrolling

const SCROLL_DOWN_KEYS = new Set([40]); // Down Arrow (Speeds up)
const SCROLL_UP_KEYS = new Set([38]); // Up Arrow (Slows down)
const PAGE_KEYS = new Set([33, 34]); // Page Up, Page Down (Pass-through)

let isScrolling = false, isPaused = false, scrollSpeed = 0, lastUpdateTime, realY;
const scrollElement = document.scrollingElement || document.documentElement;
let hudTimeout;

// === HUD DISPLAY ===
const hud = Object.assign(document.createElement("div"), {
    style: `position:fixed; bottom:10px; right:10px; padding:5px 10px; background:rgba(0,0,0,0.7);
            color:#fff; font-size:14px; font-family:Arial; border-radius:5px; z-index:9999; display:none`
});
document.body.appendChild(hud);

// === EVENT LISTENERS ===
window.addEventListener('keydown', (e) => {
    if (e.ctrlKey || e.shiftKey) return; // Prevent conflicts with other shortcuts

    if (e.keyCode === START_KEY && e.altKey) {
        e.preventDefault();
        isScrolling ? changeSpeed(SPEED_MULTIPLIER) : startScrolling();
    } else if (isScrolling) {
        if (e.keyCode === PAUSE_KEY) {
            e.preventDefault();
            togglePause();
        } else if (STOP_KEYS.has(e.keyCode)) {
            e.preventDefault();
            stopScrolling();
        } else if (SCROLL_DOWN_KEYS.has(e.keyCode)) {
            e.preventDefault();
            changeSpeed(SPEED_MULTIPLIER);
        } else if (SCROLL_UP_KEYS.has(e.keyCode)) {
            e.preventDefault();
            changeSpeed(SLOWDOWN_MULTIPLIER);
        } else if (PAGE_KEYS.has(e.keyCode)) {
            realY = scrollElement.scrollTop; // ✅ Updates memory only (no pausing)
        }
    } else if (isPaused) {
        if (PAGE_KEYS.has(e.keyCode) || SCROLL_DOWN_KEYS.has(e.keyCode) || SCROLL_UP_KEYS.has(e.keyCode)) {
            realY = scrollElement.scrollTop; // ✅ Updates memory but does not resume
        } else if (e.keyCode === PAUSE_KEY) {
            togglePause();
        } else if (STOP_KEYS.has(e.keyCode)) {
            e.preventDefault();
            stopScrolling();
        }
    }
}, { capture: true });

// === DETECT MOUSE WHEEL SCROLLING ===
window.addEventListener('wheel', (e) => {
    if (isScrolling) {
        e.preventDefault();
        isPaused = true;
        updateHUD();
    } else {
        realY = scrollElement.scrollTop; // ✅ Always update memory during pause
    }
}, { passive: true });

// === DETECT MANUAL PAGE UP / PAGE DOWN SCROLLING ===
window.addEventListener('scroll', () => {
    if (isPaused || isScrolling) {
        realY = scrollElement.scrollTop; // ✅ Always update memory on manual scroll
    }
}, { passive: true });

// === TOGGLE PAUSE/RESUME ===
const togglePause = () => {
    isPaused = !isPaused;
    updateHUD();
    if (!isPaused) {
        lastUpdateTime = performance.now(); // Prevents jumps after resuming
        requestAnimationFrame(scrollLoop);
    }
};

// === CHANGE SCROLL SPEED ===
const changeSpeed = (multiplier) => {
    scrollSpeed = Math.max(5, scrollSpeed * multiplier);
    updateHUD();
};

// === START AUTO-SCROLLING ===
const startScrolling = () => {
    isScrolling = true;
    isPaused = false;
    scrollSpeed = INITIAL_SPEED;
    realY = scrollElement.scrollTop;
    lastUpdateTime = performance.now();
    updateHUD();
    requestAnimationFrame(scrollLoop);
};

// === STOP AUTO-SCROLLING ===
const stopScrolling = () => {
    isScrolling = isPaused = false;
    scrollSpeed = 0;
    hud.style.display = "none";
};

// === MAIN SCROLL LOOP ===
const scrollLoop = (timestamp) => {
    if (!isScrolling || isPaused) return;
    realY += (scrollSpeed * (timestamp - lastUpdateTime)) / 1000;
    scrollElement.scrollTop = Math.floor(realY);
    lastUpdateTime = timestamp;
    requestAnimationFrame(scrollLoop);
};

// === HUD DISPLAY FUNCTION ===
const updateHUD = () => {
    hud.textContent = isPaused
        ? `PAUSED (Speed: ${scrollSpeed.toFixed(1)} px/s)`
        : `Speed: ${scrollSpeed.toFixed(1)} px/s`;
    hud.style.display = "block";
    clearTimeout(hudTimeout);
    if (!isPaused) hudTimeout = setTimeout(() => (hud.style.display = "none"), 2000);
};

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址