// ==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;
}
});
})();