Ultra-light OBS cursor overlay with pointer tracking + robust DOM-safe injection
// ==UserScript==
// @name Universal OBS Mouse Tracker
// @namespace universal.obs.mouse.tracker.hybrid
// @version 1.6.0
// @description Ultra-light OBS 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();
}
})();