移动端网页元素替换与编辑工具

替换网页中的元素为本地图片,支持缩放、推动和编辑操作,保持原始比例,修改为音符图标🎶,淡绿色背景,支持隐藏/显示按钮

// ==UserScript==
// @name         移动端网页元素替换与编辑工具
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  替换网页中的元素为本地图片,支持缩放、推动和编辑操作,保持原始比例,修改为音符图标🎶,淡绿色背景,支持隐藏/显示按钮
// @author       You
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// ==/UserScript==

(function() {
    'use strict';

    // 默认值:显示按钮
    let isButtonVisible = GM_getValue('buttonVisible', true);

    // 加载CSS样式
    GM_addStyle(`
        .edit-tools-btn {
            position: fixed;
            top: 10px;
            left: 10px;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: #90EE90; /* 淡绿色背景 */
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            font-size: 22px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            z-index: 99999;
        }
        .edit-tools-menu {
            display: none;
            position: fixed;
            top: 60px;
            left: 10px;
            background-color: white;
            border: 1px solid #ccc;
            padding: 10px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            z-index: 99999;
        }
        .edit-tools-menu.active {
            display: block;
        }
        .hidden {
            display: none !important;
        }
    `);

    // 创建编辑工具按钮
    const button = document.createElement('div');
    button.className = 'edit-tools-btn';
    button.innerText = '🎶';  // 使用 🎶 音符符号代替
    document.body.appendChild(button);

    // 创建功能菜单
    const menu = document.createElement('div');
    menu.className = 'edit-tools-menu';
    menu.innerHTML = `
        <button id="start-edit">开始编辑</button>
        <button id="end-edit">结束编辑</button>
        <button id="replace-img">替换为本地图片</button>
    `;
    document.body.appendChild(menu);

    // 初始化按钮的显示状态
    if (!isButtonVisible) {
        button.classList.add('hidden');
    }

    // 注册油猴菜单命令
    GM_registerMenuCommand(isButtonVisible ? '隐藏小圆按钮' : '显示小圆按钮', toggleButtonVisibility);

    // 切换按钮可见性
    function toggleButtonVisibility() {
        if (button.classList.contains('hidden')) {
            button.classList.remove('hidden');
            isButtonVisible = true;
        } else {
            button.classList.add('hidden');
            isButtonVisible = false;
        }
        GM_setValue('buttonVisible', isButtonVisible);

        // 更新油猴菜单中的选项
        GM_registerMenuCommand(isButtonVisible ? '隐藏小圆按钮' : '显示小圆按钮', toggleButtonVisibility);
    }

    // 始终保留点击事件监听器
    button.addEventListener('click', toggleMenu);

    // 切换菜单显示
    function toggleMenu() {
        menu.classList.toggle('active');
    }

    // 编辑操作
    let isEditing = false;
    let selectedElement = null;

    document.getElementById('start-edit').addEventListener('click', function() {
        isEditing = true;
        document.body.addEventListener('click', selectElement);
    });

    document.getElementById('end-edit').addEventListener('click', function() {
        isEditing = false;
        document.body.removeEventListener('click', selectElement);
        if (selectedElement) {
            selectedElement.classList.remove('editable');
            selectedElement = null;
        }
    });

    document.getElementById('replace-img').addEventListener('click', function() {
        if (selectedElement && selectedElement.tagName.toLowerCase() === 'img') {
            const fileInput = document.createElement('input');
            fileInput.type = 'file';
            fileInput.accept = 'image/*';
            fileInput.style.display = 'none';

            // 监听文件选择事件
            fileInput.addEventListener('change', function(event) {
                const file = event.target.files[0];
                if (file) {
                    const reader = new FileReader();
                    reader.onload = function(e) {
                        const img = new Image();
                        img.src = e.target.result;

                        img.onload = function() {
                            // 获取图片的原始宽高
                            const originalWidth = img.width;
                            const originalHeight = img.height;

                            // 计算图片的原始比例
                            const aspectRatio = originalWidth / originalHeight;

                            // 获取选中元素的尺寸
                            const containerWidth = selectedElement.offsetWidth;
                            const containerHeight = selectedElement.offsetHeight;

                            // 计算合理的缩放尺寸
                            let newWidth = containerWidth;
                            let newHeight = containerWidth / aspectRatio;

                            // 如果高度超出了容器,则按高度缩放
                            if (newHeight > containerHeight) {
                                newHeight = containerHeight;
                                newWidth = containerHeight * aspectRatio;
                            }

                            // 替换图片并调整大小
                            selectedElement.src = e.target.result;
                            selectedElement.style.width = `${newWidth}px`;
                            selectedElement.style.height = `${newHeight}px`;

                            // 结束编辑状态
                            selectedElement.classList.remove('editable');
                            selectedElement = null;
                        };
                    };
                    reader.readAsDataURL(file);
                }
            });

            document.body.appendChild(fileInput);
            fileInput.click();
            document.body.removeChild(fileInput);
        } else {
            alert('请先选择一个图片元素');
        }
    });

    // 选择元素
    function selectElement(e) {
        if (isEditing) {
            const element = e.target;
            if (element !== button && element !== menu && !element.classList.contains('edit-tools-btn')) {
                if (selectedElement) {
                    selectedElement.classList.remove('editable');
                }
                if (element.tagName.toLowerCase() === 'img') {
                    selectedElement = element;
                    selectedElement.classList.add('editable');
                } else {
                    alert('请选择一个图片元素');
                }
            }
        }
    }
})();