// ==UserScript== // @name Webpage Background Adjuster // @namespace http://tampermonkey.net/ // @version 1.15 // @description 调整网页背景的透明度、颜色遮罩、模糊度,并支持上传本地图片作为背景。按钮位置可通过菜单选择,支持贴边效果。 // @author Grey333 // @match *://*/* // @grant GM_setValue // @grant GM_getValue // @license MIT // @grant GM_registerMenuCommand // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 默认设置 const defaultSettings = { transparency: 1, blur: 0, overlayColor: 'transparent', overlayOpacity: 0, togglePosition: 'right-top', // 默认右上 toggleOffset: 10 // 默认偏移量 10px }; // 加载保存的设置 let settings = JSON.parse(GM_getValue('settings', JSON.stringify(defaultSettings))); // 创建样式元素 const style = document.createElement('style'); style.id = 'background-adjuster-style'; document.head.appendChild(style); // 设置初始 CSS 变量 document.body.style.setProperty('--transparency', settings.transparency); document.body.style.setProperty('--blur', settings.blur === 0 ? 'none' : `blur(${settings.blur}px)`); document.body.style.setProperty('--overlay-color', settings.overlayColor); document.body.style.setProperty('--overlay-opacity', settings.overlayOpacity); // 添加优化后的 CSS 样式 style.textContent = ` body::before { content: ""; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -2; background: inherit; opacity: var(--transparency); filter: var(--blur); } body::after { content: ""; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: -1; background: var(--overlay-color); opacity: var(--overlay-opacity); } body { background: transparent !important; } #bg-adjuster-panel { position: fixed; top: 60px; right: 10px; background: rgba(255, 255, 255, 0.95); border: none; padding: 20px; border-radius: 15px; box-shadow: 0 6px 20px rgba(0,0,0,0.15); z-index: 9999; display: none; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; width: 280px; max-height: 80vh; overflow-y: auto; } #bg-adjuster-toggle { position: fixed; right: -20px; /* 默认贴边,只显示一半 */ z-index: 10000; background: rgba(255, 255, 255, 0.3); backdrop-filter: blur(5px); border: none; padding: 10px; cursor: pointer; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: right 0.3s ease; } #bg-adjuster-toggle:hover { right: 10px !important; /* 鼠标悬停时完全显示,强制覆盖 */ } #bg-adjuster-toggle::before { content: "🎨"; font-size: 20px; } #bg-adjuster-panel label { display: flex; align-items: center; margin: 15px 0; font-size: 14px; color: #333; } #bg-adjuster-panel input[type="range"] { flex: 1; margin: 0 10px; height: 10px; border-radius: 5px; background: #e0e0e0; position: relative; outline: none; cursor: pointer; appearance: none; } #bg-adjuster-panel input[type="range"]::-webkit-slider-runnable-track { height: 10px; border-radius: 5px; } #bg-adjuster-panel input[type="range"]::-moz-range-track { height: 10px; border-radius: 5px; } #bg-adjuster-panel input[type="range"]::-webkit-slider-thumb { appearance: none; width: 18px; height: 18px; background: linear-gradient(135deg, #4a90e2, #357abd); border-radius: 50%; border: 2px solid #fff; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2); margin-top: -4px; } #bg-adjuster-panel input[type="range"]::-moz-range-thumb { width: 18px; height: 18px; background: linear-gradient(135deg, #4a90e2, #357abd); border-radius: 50%; border: 2px solid #fff; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.2); } #bg-adjuster-panel .percentage { width: 40px; text-align: right; font-size: 12px; color: #666; } #bg-adjuster-panel .color-btn { width: 24px; height: 24px; border-radius: 50%; border: 2px solid #ddd; cursor: pointer; margin-right: 8px; transition: transform 0.2s, box-shadow 0.2s; } #bg-adjuster-panel .color-btn:hover { transform: scale(1.2); box-shadow: 0 0 4px rgba(0,0,0,0.3); } #bg-adjuster-panel .color-btn:active { transform: scale(1.1); box-shadow: 0 0 6px rgba(0,0,0,0.4); } #bg-adjuster-panel #none-btn { background: transparent; border: 2px dashed #ccc; } #bg-adjuster-panel #yellow-btn { background: #ffff00; } #bg-adjuster-panel #green-btn { background: #00ff00; } #bg-adjuster-panel #custom-color { width: 40px; height: 40px; padding: 0; border: 2px solid #ddd; border-radius: 8px; cursor: pointer; margin-left: auto; } #bg-adjuster-panel button { padding: 6px 12px; cursor: pointer; border-radius: 8px; border: none; background: #f0f0f0; font-size: 12px; transition: background 0.2s; } #bg-adjuster-panel button:hover { background: #e0e0e0; } #bg-adjuster-panel #reset-btn { background: #ff3b30; color: white; } #bg-adjuster-panel #reset-btn:hover { background: #e6392e; } #bg-image-label { display: block; margin: 15px 0; font-size: 14px; color: #333; white-space: nowrap; } #bg-image-label input[type="file"] { width: 100%; font-size: 12px; margin-top: 5px; } `; // 创建 UI 面板 const panel = document.createElement('div'); panel.id = 'bg-adjuster-panel'; document.body.appendChild(panel); // UI 面板内容 panel.innerHTML = `

背景调节器

`; // 创建切换按钮 const toggleBtn = document.createElement('div'); toggleBtn.id = 'bg-adjuster-toggle'; document.body.appendChild(toggleBtn); // 切换面板显示/隐藏 toggleBtn.addEventListener('click', (e) => { e.stopPropagation(); panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; }); // 点击面板外关闭 document.addEventListener('click', (e) => { if (!panel.contains(e.target) && !toggleBtn.contains(e.target) && panel.style.display === 'block') { panel.style.display = 'none'; } }); // 防止面板内部点击冒泡到外部关闭 panel.addEventListener('click', (e) => { e.stopPropagation(); }); // 获取 UI 元素 const transparencySlider = document.getElementById('transparency-slider'); const blurSlider = document.getElementById('blur-slider'); const noneBtn = document.getElementById('none-btn'); const yellowBtn = document.getElementById('yellow-btn'); const greenBtn = document.getElementById('green-btn'); const customColor = document.getElementById('custom-color'); const overlayOpacity = document.getElementById('overlay-opacity'); const overlayOpacityLabel = document.getElementById('overlay-opacity-label'); const bgImageInput = document.getElementById('bg-image-input'); const resetBtn = document.getElementById('reset-btn'); const transparencyPercentage = transparencySlider.nextElementSibling; const blurPercentage = blurSlider.nextElementSibling; const overlayOpacityPercentage = overlayOpacity.nextElementSibling; // 更新设置和 CSS 变量的函数 function updateSettings() { settings.transparency = parseFloat(transparencySlider.value); settings.blur = parseInt(blurSlider.value); settings.overlayColor = customColor.value === '#ffffff' && overlayOpacity.value == 0 ? 'transparent' : customColor.value; settings.overlayOpacity = parseFloat(overlayOpacity.value); document.body.style.setProperty('--transparency', settings.transparency); document.body.style.setProperty('--blur', settings.blur === 0 ? 'none' : `blur(${settings.blur}px)`); document.body.style.setProperty('--overlay-color', settings.overlayColor); document.body.style.setProperty('--overlay-opacity', settings.overlayOpacity); GM_setValue('settings', JSON.stringify(settings)); transparencyPercentage.textContent = `${Math.round(settings.transparency * 100)}%`; blurPercentage.textContent = `${Math.round((settings.blur / 20) * 100)}%`; overlayOpacityPercentage.textContent = `${Math.round(settings.overlayOpacity * 100)}%`; transparencySlider.style.background = `linear-gradient(to right, #4a90e2 ${settings.transparency * 100}%, #e0e0e0 ${settings.transparency * 100}%)`; blurSlider.style.background = `linear-gradient(to right, #4a90e2 ${(settings.blur / 20) * 100}%, #e0e0e0 ${(settings.blur / 20) * 100}%)`; overlayOpacity.style.background = `linear-gradient(to right, #4a90e2 ${settings.overlayOpacity * 100}%, #e0e0e0 ${settings.overlayOpacity * 100}%)`; } // 为进度条添加事件监听并阻止冒泡 transparencySlider.addEventListener('input', (e) => { e.stopPropagation(); updateSettings(); }); blurSlider.addEventListener('input', (e) => { e.stopPropagation(); updateSettings(); }); overlayOpacity.addEventListener('input', (e) => { e.stopPropagation(); updateSettings(); }); overlayOpacityLabel.addEventListener('click', (e) => e.stopPropagation()); customColor.addEventListener('change', updateSettings); // 为颜色按钮添加事件监听 noneBtn.addEventListener('click', (e) => { e.stopPropagation(); customColor.value = '#ffffff'; overlayOpacity.value = 0; updateSettings(); }); yellowBtn.addEventListener('click', (e) => { e.stopPropagation(); customColor.value = '#ffff00'; if (settings.overlayOpacity === 0) overlayOpacity.value = 0.5; updateSettings(); }); greenBtn.addEventListener('click', (e) => { e.stopPropagation(); customColor.value = '#00ff00'; if (settings.overlayOpacity === 0) overlayOpacity.value = 0.5; updateSettings(); }); // 处理背景图片上传 bgImageInput.addEventListener('change', function() { const file = this.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { document.body.style.setProperty('--original-bg-image', `url(${e.target.result})`); style.textContent += ` body::before { background-image: var(--original-bg-image); background-size: cover; background-repeat: no-repeat; } `; }; reader.readAsDataURL(file); } }); // 重置按钮功能 resetBtn.addEventListener('click', (e) => { e.stopPropagation(); settings = Object.assign({}, defaultSettings); transparencySlider.value = settings.transparency; blurSlider.value = settings.blur; customColor.value = '#ffffff'; overlayOpacity.value = 0; document.body.style.setProperty('--transparency', settings.transparency); document.body.style.setProperty('--blur', 'none'); document.body.style.setProperty('--overlay-color', 'transparent'); document.body.style.setProperty('--overlay-opacity', 0); document.body.style.removeProperty('--original-bg-image'); applyTogglePosition(); GM_setValue('settings', JSON.stringify(settings)); style.textContent = style.textContent.replace(/body::before\s*{\s*background-image:[^}]*;\s*background-size:[^}]*;\s*background-repeat:[^}]*;\s*}/g, ''); transparencyPercentage.textContent = `${Math.round(settings.transparency * 100)}%`; blurPercentage.textContent = `${Math.round((settings.blur / 20) * 100)}%`; overlayOpacityPercentage.textContent = `${Math.round(settings.overlayOpacity * 100)}%`; updateSettings(); }); // 应用按钮位置 function applyTogglePosition() { // 重置所有位置相关样式 toggleBtn.style.right = '-20px'; // 默认贴边 toggleBtn.style.left = 'auto'; toggleBtn.style.top = '10'; toggleBtn.style.bottom = 'auto'; toggleBtn.style.transform = 'none'; // 根据 togglePosition 应用位置 switch (settings.togglePosition) { case 'right-top': toggleBtn.style.top = `${settings.toggleOffset}px`; break; case 'right-middle': toggleBtn.style.top = '50%'; toggleBtn.style.transform = 'translateY(-50%)'; break; case 'right-bottom': toggleBtn.style.bottom = `${settings.toggleOffset}px`; break; default: toggleBtn.style.top = '10px'; // 防止无效值 } } // Tampermonkey 菜单选项 console.log('Registering menu commands...'); GM_registerMenuCommand('Set Position: Top Right', () => { console.log('Selected Top Right'); settings.togglePosition = 'right-top'; settings.toggleOffset = 10; applyTogglePosition(); GM_setValue('settings', JSON.stringify(settings)); }); GM_registerMenuCommand('Set Position: Middle Right', () => { console.log('Selected Middle Right'); settings.togglePosition = 'right-middle'; settings.toggleOffset = 0; applyTogglePosition(); GM_setValue('settings', JSON.stringify(settings)); }); GM_registerMenuCommand('Set Position: Bottom Right', () => { console.log('Selected Bottom Right'); settings.togglePosition = 'right-bottom'; settings.toggleOffset = 10; applyTogglePosition(); GM_setValue('settings', JSON.stringify(settings)); }); GM_registerMenuCommand('Set Vertical Offset (px)', () => { console.log('Setting offset'); const offset = prompt('Enter vertical offset (px, 0-100):', settings.toggleOffset); const parsedOffset = parseInt(offset); if (!isNaN(parsedOffset) && parsedOffset >= 0 && parsedOffset <= 100) { settings.toggleOffset = parsedOffset; applyTogglePosition(); GM_setValue('settings', JSON.stringify(settings)); } else { alert('Please enter a valid number (0-100)'); } }); // 初始化设置 applyTogglePosition(); updateSettings(); console.log('Initialized with position:', settings.togglePosition, 'offset:', settings.toggleOffset); })();