Greasy Fork

Greasy Fork is available in English.

Webpage Background Adjuster

调整网页背景的透明度、颜色遮罩、模糊度,并支持上传本地图片作为背景。通过Tampermonkey菜单调整设置。

当前为 2025-03-04 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Webpage Background Adjuster
// @namespace    http://tampermonkey.net/
// @version      1.35
// @description  调整网页背景的透明度、颜色遮罩、模糊度,并支持上传本地图片作为背景。通过Tampermonkey菜单调整设置。
// @author       Grey333
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// @grant        GM_registerMenuCommand
// ==/UserScript==

(function() {
    'use strict';

    // 默认设置
    const defaultSettings = {
        transparency: 1,
        blur: 0,
        overlayColor: 'transparent',
        overlayOpacity: 0
    };

    // 加载保存的设置
    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: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            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-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-adjuster-panel #close-btn {
            background: #4a90e2;
            color: white;
        }
        #bg-adjuster-panel #close-btn:hover {
            background: #357abd;
        }
        #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 = `
        <h3 style="margin: 0 0 20px 0; font-size: 16px; text-align: center; color: #333;">背景调节器</h3>
        <label>透明度: <input type="range" min="0" max="1" step="0.01" id="transparency-slider" value="${settings.transparency}"><span class="percentage">${Math.round(settings.transparency * 100)}%</span></label>
        <label>模糊度: <input type="range" min="0" max="20" step="1" id="blur-slider" value="${settings.blur}"><span class="percentage">${Math.round((settings.blur / 20) * 100)}%</span></label>
        <div id="color-overlay-section">
            <label style="display: flex; align-items: center;">颜色遮罩:
                <button class="color-btn" id="none-btn" title="无"></button>
                <button class="color-btn" id="yellow-btn" title="黄色"></button>
                <button class="color-btn" id="green-btn" title="绿色"></button>
                <input type="color" id="custom-color" value="${settings.overlayColor === 'transparent' ? '#ffffff' : settings.overlayColor}" title="自定义颜色">
            </label>
        </div>
        <div id="overlay-opacity-section">
            <label id="overlay-opacity-label">遮罩透明度: <input type="range" min="0" max="1" step="0.01" id="overlay-opacity" value="${settings.overlayOpacity}"><span class="percentage">${Math.round(settings.overlayOpacity * 100)}%</span></label>
        </div>
        <label id="bg-image-label">背景图片:<input type="file" id="bg-image-input" accept="image/*"></label>
        <button id="reset-btn" style="width: 100%; margin-top: 15px;">重置</button>
        <button id="close-btn" style="width: 100%; margin-top: 10px;">关闭</button>
    `;

    // 获取 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 closeBtn = document.getElementById('close-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', updateSettings);
    blurSlider.addEventListener('input', updateSettings);
    overlayOpacity.addEventListener('input', updateSettings);
    customColor.addEventListener('change', updateSettings);

    // 为颜色按钮添加事件监听
    noneBtn.addEventListener('click', () => {
        customColor.value = '#ffffff';
        overlayOpacity.value = 0;
        updateSettings();
    });
    yellowBtn.addEventListener('click', () => {
        customColor.value = '#ffff00';
        if (settings.overlayOpacity === 0) overlayOpacity.value = 0.5;
        updateSettings();
    });
    greenBtn.addEventListener('click', () => {
        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', () => {
        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');
        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();
    });

    // 关闭面板
    closeBtn.addEventListener('click', () => {
        panel.style.display = 'none';
    });

    // 点击面板外关闭
    document.addEventListener('click', (e) => {
        if (!panel.contains(e.target) && panel.style.display === 'block') {
            panel.style.display = 'none';
        }
    });

    // 防止面板内部点击冒泡到外部关闭
    panel.addEventListener('click', (e) => {
        e.stopPropagation();
    });

    // Tampermonkey 菜单选项
    GM_registerMenuCommand('打开背景调节器', () => {
        panel.style.display = 'block';
    });

    // 初始化设置
    updateSettings();
})();