Mouse Tracker

Ultra-lean Mouse cursor overlay with pointer tracking + robust DOM-safe injection

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

// ==UserScript==
// @name         Mouse Tracker
// @namespace    ultralean.universal.mouse.tracker
// @version      1.6.0
// @description  Ultra-lean Mouse cursor overlay with pointer tracking + robust DOM-safe injection
// @author       Michael Stutesman
// @license      MIT
// @match        *://*/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(() => {
    'use strict';

    // --------------------------------------------------
    // Singleton Guard (hard safe)
    // --------------------------------------------------
    if (globalThis.__OBS_MOUSE_TRACKER__) return;
    globalThis.__OBS_MOUSE_TRACKER__ = true;

    // --------------------------------------------------
    // Config
    // --------------------------------------------------
    const SIZE = 18;
    const COLOR = 'rgba(204,204,204,0.9)';
    const BORDER = 2;
    const BORDER_COLOR = 'rgba(255,255,255,0.9)';
    const SHADOW = '0 0 10px rgba(0,200,255,0.8)';
    const Z = 2147483647;
    const HIDE_DELAY = 80;

    // --------------------------------------------------
    // State
    // --------------------------------------------------
    let hideTimeout = 0;
    let rafId = 0;
    let lastX = 0;
    let lastY = 0;

    // --------------------------------------------------
    // Elements (declared early, mounted safely later)
    // --------------------------------------------------
    const container = document.createElement('div');
    const tracker = document.createElement('div');

    Object.assign(container.style, {
        position: 'fixed',
        inset: '0',
        pointerEvents: 'none',
        zIndex: Z,
        contain: 'strict',
        transform: 'translate3d(0,0,0)',
    });

    Object.assign(tracker.style, {
        width: `${SIZE}px`,
        height: `${SIZE}px`,
        borderRadius: '50%',
        background: COLOR,
        border: `${BORDER}px solid ${BORDER_COLOR}`,
        boxShadow: SHADOW,
        pointerEvents: 'none',
        transform: 'translate3d(-50%,-50%,0)',
        opacity: '0',
        transition: 'opacity 0.1s linear',
        willChange: 'transform, opacity'
    });

    container.appendChild(tracker);

    // --------------------------------------------------
    // Render (rAF optimized)
    // --------------------------------------------------
    const render = () => {
        rafId = 0;

        tracker.style.transform =
            `translate3d(${lastX}px,${lastY}px,0) translate(-50%,-50%)`;

        tracker.style.opacity = '1';

        clearTimeout(hideTimeout);
        hideTimeout = setTimeout(() => {
            tracker.style.opacity = '0';
        }, HIDE_DELAY);
    };

    // --------------------------------------------------
    // Input (fast path — pointer events)
    // --------------------------------------------------
    const onMove = (e) => {
        lastX = e.clientX;
        lastY = e.clientY;

        if (!rafId) {
            rafId = requestAnimationFrame(render);
        }
    };

    const onLeave = () => {
        tracker.style.opacity = '0';
    };

    // --------------------------------------------------
    // Safe mount (DOM-ready tolerant)
    // --------------------------------------------------
    const mount = () => {
        const parent = document.body || document.documentElement;
        if (!parent) return;

        parent.appendChild(container);

        // Attach input AFTER mount (prevents edge timing bugs)
        window.addEventListener('pointermove', onMove, { passive: true });
        document.addEventListener('pointerleave', onLeave);
    };

    // --------------------------------------------------
    // Init guard (handles document-start safely)
    // --------------------------------------------------
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', mount);
    } else {
        mount();
    }

})();