您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
cool, eh?
// ==UserScript== // @name Fancy Custom Cursor // @namespace https://guest4242.neocities.org/pre/ // @version 2025.08.25.2 // @description cool, eh? // @author Guest4242 // @match *://*/* // @grant GM_addStyle // @run-at document-end // @connect * // @license MIT // ==/UserScript== (function () { 'use strict'; // ---- Config stuff...I guess? ---- const FA_CSS = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css"; const CLICK_DOWN_URL = "https://raw.githubusercontent.com/Guest4242s-Website-Stuff/sounds/main/ClickDown.ogg"; const CLICK_UP_URL = "https://raw.githubusercontent.com/Guest4242s-Website-Stuff/sounds/main/ClickUp.ogg"; const ZINDEX = 999999; const lerp = (a, b, n) => (1 - n) * a + n * b; const isTextEditable = el => { if (!el) return false; const t = el.tagName; if (!t) return false; if (t === 'INPUT' || t === 'TEXTAREA' || el.isContentEditable) return true; const role = el.getAttribute && el.getAttribute('role'); if (role === 'textbox') return true; return false; }; const globalCSS = ` /* global hide native cursor on all elements and pseudo-elements */ * , *::before, *::after { cursor: none !important; } /* custom cursor element styling */ .tm-fancy-cursor { position: fixed; left: 0; top: 0; pointer-events: none; /* so it never blocks interactions */ user-select: none; font-size: 24px; line-height: 1; /* IMPORTANT: no transform transition, we animate per-frame */ transition: color 0.12s ease, text-shadow 0.12s ease; will-change: transform; z-index: ${ZINDEX} !important; -webkit-text-stroke: 1px black; text-stroke: 1px black; text-shadow: 0 0 4px rgba(0,0,0,0.4); display: inline-block; } .tm-fallback-glyph { font-family: system-ui, "Segoe UI Symbol", "Noto Color Emoji", sans-serif; } `; try { GM_addStyle(globalCSS); } catch (e) { const s = document.createElement('style'); s.textContent = globalCSS; document.head.appendChild(s); } const c = document.createElement('i'); c.className = 'tm-fancy-cursor tm-fallback-glyph'; c.textContent = '\u25B6'; // fallback glyph thingy just in case c.style.color = 'white'; c.style.pointerEvents = 'none'; document.body.appendChild(c); function tryLoadFontAwesome() { return new Promise((resolve) => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = FA_CSS; link.crossOrigin = 'anonymous'; link.onload = () => resolve(true); link.onerror = () => resolve(false); document.head.appendChild(link); setTimeout(() => resolve(false), 2500); }); } function makeAudio(src) { try { const a = new Audio(src); a.preload = 'auto'; a.crossOrigin = 'anonymous'; return a; } catch (e) { return null; } } const clickDownSound = makeAudio(CLICK_DOWN_URL); const clickUpSound = makeAudio(CLICK_UP_URL); // ---- State ---- let mouseX = window.innerWidth / 2, mouseY = window.innerHeight / 2; let currentX = mouseX, currentY = mouseY; let scale = 1; let targetScale = 1; const SCALE_LERP = 0.22; let isDragging = false; let FA_AVAILABLE = false; function setFaIcon(iconShortName) { if (FA_AVAILABLE) { c.className = `fa-solid ${iconShortName} tm-fancy-cursor`; c.textContent = ''; } else { c.className = 'tm-fancy-cursor tm-fallback-glyph'; if (iconShortName === 'fa-i') c.textContent = '\u2014'; else if (iconShortName === 'fa-hand-point-up') c.textContent = '\u261A'; else if (iconShortName === 'fa-hand-back-fist') c.textContent = '\u270A'; else c.textContent = '\u25B6'; } } function setIconForElement(el) { if (!el) return; if (isDragging) { setFaIcon('fa-hand-back-fist'); return; } if (isTextEditable(el) || el.tagName === "P" || el.tagName === "SPAN" || el.tagName === "H1" || el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "H2" || el.tagName === "H3" || el.tagName === "H4" || el.tagName === "H5" || el.tagName === "H6") { setFaIcon('fa-i'); return; } let check = el; while (check) { const tag = check.tagName || ''; if (tag === 'BUTTON' || tag === 'A' || (check.classList && check.classList.contains('btn'))) { setFaIcon('fa-hand-point-up'); return; } check = check.parentElement; } setFaIcon('fa-arrow-pointer'); } function animateCursor() { currentX = lerp(currentX, mouseX, 0.22); currentY = lerp(currentY, mouseY, 0.22); scale = lerp(scale, targetScale, SCALE_LERP); c.style.transform = `translate3d(${Math.round(currentX)}px, ${Math.round(currentY)}px, 0) translate(-50%, -50%) scale(${scale})`; requestAnimationFrame(animateCursor); } function onPointerMove(e) { mouseX = e.clientX; mouseY = e.clientY; const el = document.elementFromPoint(mouseX, mouseY); setIconForElement(el); } function onPointerDown(e) { targetScale = 0.84; c.style.color = '#ddd'; c.style.textShadow = '0 0 6px rgba(255,255,255,0.8)'; if (clickDownSound) { try { clickDownSound.currentTime = 0; clickDownSound.play().catch(()=>{}); } catch(e) {} } } function onPointerUp(e) { targetScale = 1.25; c.style.color = 'white'; c.style.textShadow = '0 0 4px rgba(0,0,0,0.4)'; if (clickUpSound) { try { clickUpSound.currentTime = 0; clickUpSound.play().catch(()=>{}); } catch(e) {} } setTimeout(() => { targetScale = 1; }, 140); } function onDragStart() { isDragging = true; setFaIcon('fa-hand-back-fist'); } function onDragEnd() { isDragging = false; } (async function init() { if (!document.body) return; // ensure that the native cursor hidden try { document.documentElement.style.cursor = 'none'; } catch (e) {} FA_AVAILABLE = await tryLoadFontAwesome(); if (FA_AVAILABLE) setFaIcon('fa-arrow-pointer'); window.addEventListener('pointermove', onPointerMove, { passive: true }); window.addEventListener('pointerdown', onPointerDown, { passive: true }); window.addEventListener('pointerup', onPointerUp, { passive: true }); window.addEventListener('dragstart', onDragStart, { passive: true }); window.addEventListener('dragend', onDragEnd, { passive: true }); document.addEventListener('focusin', () => {}); document.addEventListener('focusout', () => {}); requestAnimationFrame(animateCursor); })(); })();