// ==UserScript== // @license MIT // @name 视频触屏手势控制|滑动进度+左右分控音量亮度·带浮层提示 // @namespace http://tampermonkey.net/ // @version 2.0 // @description 触屏在视频上左右滑动控制快进快退,无需全屏 // @author assistant // @match *://*/* // @grant none // @downloadURL https://update.greasyfork.icu/scripts/572494/%E8%A7%86%E9%A2%91%E8%A7%A6%E5%B1%8F%E6%89%8B%E5%8A%BF%E6%8E%A7%E5%88%B6%EF%BD%9C%E6%BB%91%E5%8A%A8%E8%BF%9B%E5%BA%A6%2B%E5%B7%A6%E5%8F%B3%E5%88%86%E6%8E%A7%E9%9F%B3%E9%87%8F%E4%BA%AE%E5%BA%A6%C2%B7%E5%B8%A6%E6%B5%AE%E5%B1%82%E6%8F%90%E7%A4%BA.user.js // @updateURL https://update.greasyfork.icu/scripts/572494/%E8%A7%86%E9%A2%91%E8%A7%A6%E5%B1%8F%E6%89%8B%E5%8A%BF%E6%8E%A7%E5%88%B6%EF%BD%9C%E6%BB%91%E5%8A%A8%E8%BF%9B%E5%BA%A6%2B%E5%B7%A6%E5%8F%B3%E5%88%86%E6%8E%A7%E9%9F%B3%E9%87%8F%E4%BA%AE%E5%BA%A6%C2%B7%E5%B8%A6%E6%B5%AE%E5%B1%82%E6%8F%90%E7%A4%BA.meta.js // ==/UserScript== (function() { 'use strict'; const CONFIG = { seekSensitivity: 0.12, brightnessSensitivity: 0.001, volumeSensitivity: 0.001, minMoveDistance: 5 }; let currentVideo = null; let startX = 0, startY = 0; let isHorizontal = false, isVertical = false; let isLeftSide = false; let lastBrightness = 1.0; // ========== 浮层相关 ========== let tip = null; let tipTimer = null; function createTip() { if (tip) return; tip = document.createElement('div'); tip.style.cssText = ` position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 10px 16px; background: rgba(0,0,0,0.7); color: #fff; border-radius: 8px; font-size: 16px; z-index: 999999; pointer-events: none; opacity: 0; transition: opacity 0.2s; white-space: nowrap; `; document.body.appendChild(tip); } function showTip(text) { createTip(); tip.textContent = text; tip.style.opacity = 1; clearTimeout(tipTimer); tipTimer = setTimeout(() => { tip.style.opacity = 0; }, 700); } // ========== 触摸逻辑 ========== document.addEventListener('touchstart', e => { const video = e.target.closest('video'); if (!video) return; currentVideo = video; const touch = e.touches[0]; const rect = video.getBoundingClientRect(); startX = touch.clientX; startY = touch.clientY; isLeftSide = touch.clientX < rect.left + rect.width / 2; isHorizontal = isVertical = false; const match = getComputedStyle(video).filter.match(/brightness\(([\d.]+)\)/); lastBrightness = match ? parseFloat(match[1]) : 1.0; }, { passive: true }); document.addEventListener('touchmove', e => { if (!currentVideo) return; const touch = e.touches[0]; const dx = touch.clientX - startX; const dy = touch.clientY - startY; const absX = Math.abs(dx); const absY = Math.abs(dy); if (!isHorizontal && !isVertical) { if (absX > absY && absX > CONFIG.minMoveDistance) isHorizontal = true; else if (absY > absX && absY > CONFIG.minMoveDistance) isVertical = true; } if (isHorizontal) { currentVideo.currentTime += dx * CONFIG.seekSensitivity; showTip(`进度 ${dx > 0 ? '+' : ''}${Math.round(dx * CONFIG.seekSensitivity)}s`); startX = touch.clientX; e.preventDefault(); } if (isVertical) { if (isLeftSide) { const delta = -dy * CONFIG.brightnessSensitivity; lastBrightness = Math.max(0.2, Math.min(2.0, lastBrightness + delta)); currentVideo.style.filter = `brightness(${lastBrightness})`; showTip(`亮度 ${Math.round(lastBrightness * 100)}%`); } else { const delta = -dy * CONFIG.volumeSensitivity; currentVideo.volume = Math.max(0, Math.min(1, currentVideo.volume + delta)); showTip(`音量 ${Math.round(currentVideo.volume * 100)}%`); } startY = touch.clientY; e.preventDefault(); } }, { passive: false }); document.addEventListener('touchend', () => { currentVideo = null; isHorizontal = isVertical = false; }); })();