// ==UserScript== // @name 移动端网页元素替换与编辑工具 // @namespace http://tampermonkey.net/ // @version 0.6 // @description 替换网页中的元素为本地图片,支持缩放、推动和编辑操作,保持原始比例,修改为音符图标🎶,淡绿色背景 // @author You // @match *://*/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 加载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 button { margin: 5px; padding: 5px 10px; cursor: pointer; } .active { display: block; } .editable { border: 2px solid red; } `); let isEditing = false; let selectedElement = null; // 创建编辑工具按钮 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 = ` `; document.body.appendChild(menu); // 显示/隐藏菜单 button.addEventListener('click', function() { menu.classList.toggle('active'); }); // 开始编辑 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('请选择一个图片元素'); } } } } // 支持双指缩放和单指推动 let initialDistance = null; let initialPosition = null; document.body.addEventListener('touchstart', function(e) { if (e.touches.length == 1) { initialPosition = { x: e.touches[0].pageX, y: e.touches[0].pageY }; } else if (e.touches.length == 2) { const dx = e.touches[1].pageX - e.touches[0].pageX; const dy = e.touches[1].pageY - e.touches[0].pageY; initialDistance = Math.sqrt(dx * dx + dy * dy); } }); document.body.addEventListener('touchmove', function(e) { if (e.touches.length == 1 && selectedElement) { const dx = e.touches[0].pageX - initialPosition.x; const dy = e.touches[0].pageY - initialPosition.y; selectedElement.style.transform = `translate(${dx}px, ${dy}px)`; } else if (e.touches.length == 2) { const dx = e.touches[1].pageX - e.touches[0].pageX; const dy = e.touches[1].pageY - e.touches[0].pageY; const newDistance = Math.sqrt(dx * dx + dy * dy); const scale = newDistance / initialDistance; if (selectedElement) { selectedElement.style.transform = `scale(${scale})`; } } }); document.body.addEventListener('touchend', function(e) { if (e.touches.length < 2) { initialDistance = null; } }); })();