您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fixes UI visibility issues for TimerHooker Unified Version.
- // ==UserScript==
- // @name TimerHooker Unified Version (UI Fix)
- // @version 4.1.0
- // @description Fixes UI visibility issues for TimerHooker Unified Version.
- // @author Combined
- // @match http://*/*
- // @run-at document-start
- // @grant none
- // @license GPL-3.0-or-later
- // @namespace https://greasyfork.org/users/1356925
- // ==/UserScript==
- (function (global) {
- let isRunning = false; // Tracks whether the timer is active
- let speedMultiplier = localStorage.getItem("timerHookerSpeed") || 2.0; // Default speed (2x)
- let autoHideTimeout; // For auto-hide functionality
- // Override timers with speed adjustment
- const overrideTimers = function (factor) {
- ["setTimeout", "setInterval"].forEach((method) => {
- window[method] = ((original) => (fn, time) => {
- // Exclude video-related timers
- const fnString = fn.toString();
- if (fnString.includes("playback") || fnString.includes("video")) {
- return original(fn, time);
- }
- return original(fn, time / factor);
- })(window[method]);
- });
- };
- const changeTimerSpeed = function (multiplier) {
- speedMultiplier = multiplier;
- localStorage.setItem("timerHookerSpeed", multiplier);
- if (isRunning) overrideTimers(speedMultiplier);
- console.log(`[TimerHooker] Timer speed changed to x${multiplier}`);
- };
- const createUI = function () {
- const style = `
- .timer-ball {
- position: fixed;
- bottom: 20px;
- right: 20px;
- width: 60px;
- height: 60px;
- border-radius: 50%;
- background-color: #4CAF50;
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
- cursor: pointer;
- touch-action: manipulation;
- transition: background-color 0.3s ease;
- z-index: 9999; /* Ensure visibility above other elements */
- }
- .timer-ball:hover {
- background-color: #45A049;
- }
- .timer-symbol {
- font-size: 24px;
- color: white;
- font-weight: bold;
- }
- .slider-container {
- position: fixed;
- bottom: 90px;
- right: 20px;
- z-index: 9999; /* Ensure visibility above other elements */
- display: none;
- background: rgba(0, 0, 0, 0.6);
- padding: 10px;
- border-radius: 10px;
- box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4);
- user-select: none;
- }
- .slider {
- width: 120px;
- }
- `;
- const styleNode = document.createElement('style');
- styleNode.type = 'text/css';
- styleNode.textContent = style;
- // Main ball UI
- const ball = document.createElement('div');
- ball.className = 'timer-ball';
- ball.innerHTML = '<div class="timer-symbol">▶</div>'; // Start symbol
- // Speed adjustment slider
- const sliderContainer = document.createElement('div');
- sliderContainer.className = 'slider-container';
- const slider = document.createElement('input');
- slider.className = 'slider';
- slider.type = 'range';
- slider.min = "1";
- slider.max = "200";
- slider.value = speedMultiplier * 100; // Scale multiplier to slider range
- slider.addEventListener('input', (event) => {
- const newSpeed = event.target.value / 100;
- changeTimerSpeed(newSpeed);
- });
- sliderContainer.appendChild(slider);
- ball.addEventListener('click', () => {
- isRunning = !isRunning;
- ball.querySelector('.timer-symbol').innerHTML = isRunning ? '■' : '▶'; // Toggle Start/Stop symbol
- overrideTimers(isRunning ? speedMultiplier : 1.0);
- sliderContainer.style.display = isRunning ? 'block' : 'none'; // Show/hide slider
- resetAutoHide(); // Reset auto-hide timer
- });
- // Add auto-hide functionality
- const resetAutoHide = function () {
- clearTimeout(autoHideTimeout);
- autoHideTimeout = setTimeout(() => {
- if (isRunning) sliderContainer.style.display = 'none';
- }, 3000);
- };
- document.body.appendChild(ball);
- document.body.appendChild(sliderContainer);
- document.head.appendChild(styleNode);
- };
- const init = function () {
- console.log("[TimerHooker] Unified version activated.");
- createUI();
- overrideTimers(speedMultiplier);
- };
- // Initialize when the DOM is loaded
- if (document.readyState === "complete") {
- init();
- } else {
- window.addEventListener("load", () => init());
- }
- })(window);