点击图片放大到屏幕显示的最大尺寸,并支持滚轮放大、拖动和旋转,点击关闭放大显示的图片,并增加切换上一张或下一张图片的功能。
// ==UserScript== // @name 图片放大油猴脚本(悬浮按钮,拖动,旋转,翻页) // @namespace http://your.namespace.com // @version 3.0 // @description 点击图片放大到屏幕显示的最大尺寸,并支持滚轮放大、拖动和旋转,点击关闭放大显示的图片,并增加切换上一张或下一张图片的功能。 // @author 肆散的尘埃i // @match https://happy.5ge.net/* // @match http*://*/* // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; // 自动执行URL列表 var urlList = [ 'https://happy.5ge.net', 'https://www.sstuku26.xyz' ]; // 添加样式 function addStyles() { GM_addStyle(` .gm-expanded-image-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); z-index: 9999; display: none; justify-content: center; align-items: center; overflow: hidden; } .gm-expanded-image { max-width: 100%; max-height: 100%; cursor: grab; user-select: none; -webkit-user-drag: none; transform-origin: center center; position: absolute; } .gm-floating-button { position: fixed; bottom: 20px; left: 20px; z-index: 10000; width: 50px; height: 50px; background-color: transparent; /* 底色改为透明 */ color: #333; /* 设置字体颜色为深灰色 */ display: flex; justify-content: center; align-items: center; cursor: pointer; font-size: 24px; border-radius: 50%; border: 2px solid #333; /* 设置边框颜色为深灰色 */ user-select: none; } .gm-rotate-left, .gm-rotate-right, .gm-close-button, .gm-prev-button, .gm-next-button { position: fixed; z-index: 10001; width: 50px; height: 50px; background-color: #333; color: white; display: flex; justify-content: center; align-items: center; cursor: pointer; font-size: 24px; border-radius: 50%; border: 2px solid #fff; display: none; } .gm-rotate-left { bottom: 20px; right: 140px; } .gm-rotate-right { bottom: 20px; right: 80px; } .gm-close-button { top: 20px; right: 20px; } .gm-prev-button { top: 50%; left: 20px; transform: translateY(-50%); } .gm-next-button { top: 50%; right: 20px; transform: translateY(-50%); } `); } // 添加悬浮图片按钮 function addFloatingButton() { var $floatingButton = document.createElement('div'); $floatingButton.classList.add('gm-floating-button'); $floatingButton.textContent = '🔍'; document.body.appendChild($floatingButton); // 点击悬浮按钮执行 disableImageClick 操作 $floatingButton.addEventListener('click', function () { show_message("悬浮图片被点击~"); // document.getElementById("adver_box") ? .remove(); disableImageClick(); }); // 使悬浮按钮可拖动 makeElementDraggable($floatingButton); } // 使元素可拖动 function makeElementDraggable(element) { var isDragging = false; var lastX = 0; var lastY = 0; element.addEventListener('mousedown', function (e) { isDragging = true; lastX = e.clientX; lastY = e.clientY; element.style.cursor = 'grabbing'; e.preventDefault(); }); document.addEventListener('mousemove', function (e) { if (isDragging) { var dx = e.clientX - lastX; var dy = e.clientY - lastY; var rect = element.getBoundingClientRect(); element.style.left = rect.left + dx + 'px'; element.style.top = rect.top + dy + 'px'; lastX = e.clientX; lastY = e.clientY; } }); document.addEventListener('mouseup', function () { if (isDragging) { isDragging = false; element.style.cursor = 'grab'; } }); } var $expandedImage; var $rotateLeftButton; var $rotateRightButton; var $closeButton; var $prevButton; var $nextButton; var scale = 1; var rotation = 0; var translateX = 0; var translateY = 0; var lastX = 0; var lastY = 0; var currentIndex = -1; var images = []; // 屏蔽图片默认点击功能 function disableImageClick() { images = Array.from(document.getElementsByTagName('img')); for (var i = 0; i < images.length; i++) { if (!images[i].hasAttribute('data-gm-enlargeable')) { images[i].setAttribute('data-gm-enlargeable', 'true'); images[i].addEventListener('click', function (e) { if (e.target.classList.contains('gm-floating-button')) { return; // 如果是悬浮按钮则不执行放大功能 } e.preventDefault(); e.stopPropagation(); currentIndex = images.indexOf(e.target); enlargeImage(e.target); // 放大图片 }); } } } // 添加放大功能 function enlargeImage(imgElement) { if (document.querySelector('.gm-expanded-image-container')) { closeEnlargedImage(document.querySelector('.gm-expanded-image-container')); } var src = imgElement.src; var $expandedContainer = document.createElement('div'); $expandedContainer.classList.add('gm-expanded-image-container'); $expandedImage = document.createElement('img'); $expandedImage.classList.add('gm-expanded-image'); $expandedImage.src = src; $expandedContainer.appendChild($expandedImage); document.body.appendChild($expandedContainer); $expandedContainer.style.display = 'flex'; // 禁止原始图片的点击行为 imgElement.style.pointerEvents = 'none'; // 禁用滚动 document.body.style.overflow = 'hidden'; // 点击遮罩层关闭放大图片 $expandedContainer.addEventListener('click', function (e) { if (e.target === $expandedContainer) { closeEnlargedImage($expandedContainer); } }); // 按Esc键关闭放大图片 document.addEventListener('keydown', function onEscPress(e) { if (e.key === 'Escape') { closeEnlargedImage($expandedContainer); document.removeEventListener('keydown', onEscPress); } }); // 键盘方向键功能 document.addEventListener('keydown', function onArrowPress(e) { if (e.key === 'ArrowLeft') { showPrevImage(); } else if (e.key === 'ArrowRight') { showNextImage(); } else if (e.key === 'ArrowUp') { rotation -= 90; $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; } else if (e.key === 'ArrowDown') { rotation += 90; $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; } }); // 鼠标拖动 $expandedImage.addEventListener('mousedown', function (e) { e.preventDefault(); lastX = e.clientX; lastY = e.clientY; function onMouseMove(e) { e.preventDefault(); var dx = e.clientX - lastX; var dy = e.clientY - lastY; translateX += dx; translateY += dy; $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; lastX = e.clientX; lastY = e.clientY; } function onMouseUp() { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); }); // 滚轮缩放 $expandedImage.addEventListener('wheel', function (e) { e.preventDefault(); var delta = e.deltaY < 0 ? -0.1 : 0.1; scale += delta; if (scale < 0.1) scale = 0.1; $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; }); $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; $expandedImage.style.transition = 'transform 0.2s ease-out'; // 显示旋转和关闭按钮 showControlButtons(); } // 显示控制按钮 function showControlButtons() { if (!$rotateLeftButton) { $rotateLeftButton = document.createElement('div'); $rotateLeftButton.classList.add('gm-rotate-left'); $rotateLeftButton.textContent = '⮜'; // 旋转左箭头 document.body.appendChild($rotateLeftButton); $rotateLeftButton.addEventListener('click', function () { rotation -= 90; // 每次左旋转90度 $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; }); } if (!$rotateRightButton) { $rotateRightButton = document.createElement('div'); $rotateRightButton.classList.add('gm-rotate-right'); $rotateRightButton.textContent = '⮞'; // 旋转右箭头 document.body.appendChild($rotateRightButton); $rotateRightButton.addEventListener('click', function () { rotation += 90; // 每次右旋转90度 $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`; }); } if (!$closeButton) { $closeButton = document.createElement('div'); $closeButton.classList.add('gm-close-button'); $closeButton.textContent = '✖'; // 关闭按钮 document.body.appendChild($closeButton); $closeButton.addEventListener('click', function () { closeEnlargedImage(document.querySelector('.gm-expanded-image-container')); }); } if (!$prevButton) { $prevButton = document.createElement('div'); $prevButton.classList.add('gm-prev-button'); $prevButton.textContent = '⮜'; // 向前按钮 document.body.appendChild($prevButton); $prevButton.addEventListener('click', function () { showPrevImage(); }); } if (!$nextButton) { $nextButton = document.createElement('div'); $nextButton.classList.add('gm-next-button'); $nextButton.textContent = '⮞'; // 向后按钮 document.body.appendChild($nextButton); $nextButton.addEventListener('click', function () { showNextImage(); }); } $rotateLeftButton.style.display = 'flex'; $rotateRightButton.style.display = 'flex'; $closeButton.style.display = 'flex'; $prevButton.style.display = 'flex'; $nextButton.style.display = 'flex'; } // 隐藏控制按钮 function hideControlButtons() { if ($rotateLeftButton) { $rotateLeftButton.style.display = 'none'; } if ($rotateRightButton) { $rotateRightButton.style.display = 'none'; } if ($closeButton) { $closeButton.style.display = 'none'; } if ($prevButton) { $prevButton.style.display = 'none'; } if ($nextButton) { $nextButton.style.display = 'none'; } } // 关闭放大图片 function closeEnlargedImage($expandedContainer) { document.body.style.overflow = 'auto'; // 取消大图查看时允许滑动 $expandedContainer.style.display = 'none'; $expandedContainer.remove(); hideControlButtons(); resetTransformations(); } // 重置转换属性 function resetTransformations() { scale = 1; rotation = 0; translateX = 0; translateY = 0; } // 切换到上一张图片 function showPrevImage() { if (currentIndex > 0) { currentIndex--; closeEnlargedImage(document.querySelector('.gm-expanded-image-container')); enlargeImage(images[currentIndex]); } } // 切换到下一张图片 function showNextImage() { if (currentIndex < images.length - 1) { currentIndex++; closeEnlargedImage(document.querySelector('.gm-expanded-image-container')); enlargeImage(images[currentIndex]); } } // 检查当前网址是否在urlList中 function checkCurrentUrl() { var currentUrl = window.location.origin; if (urlList.includes(currentUrl)) { // 如果匹配,执行操作 disableImageClick(); } } /** * 创建并显示透明提示框 * show_message('这是一个自定义的提示框!', 'center-top'); * show_message('这是一个自定义的提示框!', 'center-top', 3, 0.5, true, '#67C23A', '#fff'); * @param {string} content - 提示框中的内容 * @param {string} [position='center-top'] - 提示框的位置,值可以是 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'center-top', 'center-bottom',默认值为 'center-top' * @param {number} [autoCloseAfter=3] - 自动关闭提示框的时间(秒),默认值为 3 秒 * @param {number} [opacity=0.5] - 提示框的透明度,值范围从 0(完全透明)到 1(完全不透明),默认值为 0.5 * @param {boolean} [hasCloseButton=false] - 是否显示关闭按钮,默认值为 false * @param {string} [backgroundColor='#000'] - 提示框的背景颜色,默认值为黑色。可使用类似 Element UI 的颜色(例如 '#409EFF')。 * @param {string} [textColor='#fff'] - 提示框的文字颜色,默认值为白色。可使用类似 Element UI 的颜色(例如 '#fff')。 */ function show_message(content, position = 'center-top', autoCloseAfter = 3, opacity = 0.5, hasCloseButton = false, backgroundColor = '#000', textColor = '#fff') { // 创建提示框的样式 const style = document.createElement('style'); style.textContent = ` .custom-notification { position: fixed; background-color: ${backgroundColor}; /* 背景颜色 */ color: ${textColor}; /* 文字颜色 */ padding: 10px; border-radius: 5px; display: none; /* 默认隐藏提示框 */ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); z-index: 1000; /* 确保提示框在其他内容之上 */ transition: opacity 0.5s ease; /* 添加过渡效果 */ max-width: 300px; /* 设置最大宽度 */ overflow: hidden; /* 隐藏溢出内容 */ opacity: ${opacity}; /* 透明度 */ } .custom-notification-content { display: flex; align-items: center; /* 垂直居中对齐 */ justify-content: space-between; /* 内容和按钮在水平上分开 */ } .custom-notification button { background-color: #ff4c4c; /* 红色背景 */ color: #fff; /* 白色文字 */ border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; margin-left: 10px; /* 按钮和内容之间的间距 */ } .custom-notification button:hover { background-color: #ff0000; /* 鼠标悬停时更深的红色 */ } `; document.head.appendChild(style); // 创建提示框的 HTML const notification = document.createElement('div'); notification.className = 'custom-notification'; notification.innerHTML = ` <div class="custom-notification-content"> <p>${content}</p> ${hasCloseButton ? '<button id="closeNotification">✖</button>' : ''} </div> `; document.body.appendChild(notification); // 根据位置参数设置提示框的位置 switch (position) { case 'top-right': notification.style.top = '20px'; notification.style.right = '20px'; notification.style.bottom = ''; notification.style.left = ''; break; case 'top-left': notification.style.top = '20px'; notification.style.left = '20px'; notification.style.bottom = ''; notification.style.right = ''; break; case 'bottom-right': notification.style.bottom = '20px'; notification.style.right = '20px'; notification.style.top = ''; notification.style.left = ''; break; case 'bottom-left': notification.style.bottom = '20px'; notification.style.left = '20px'; notification.style.top = ''; notification.style.right = ''; break; case 'center-top': notification.style.top = '20px'; notification.style.left = '50%'; notification.style.transform = 'translateX(-50%)'; notification.style.bottom = ''; notification.style.right = ''; break; case 'center-bottom': notification.style.bottom = '20px'; notification.style.left = '50%'; notification.style.transform = 'translateX(-50%)'; notification.style.top = ''; notification.style.right = ''; break; default: console.warn('Unknown position:', position); // 默认位置为 center-top notification.style.top = '20px'; notification.style.left = '50%'; notification.style.transform = 'translateX(-50%)'; notification.style.bottom = ''; notification.style.right = ''; break; } // 显示提示框 notification.style.display = 'block'; // 关闭提示框的函数 function closeNotification() { notification.style.opacity = '0'; setTimeout(() => { notification.style.display = 'none'; }, 500); // 匹配过渡效果的时间 } // 如果有关闭按钮,为其添加事件监听 if (hasCloseButton) { const closeNotificationButton = document.getElementById('closeNotification'); closeNotificationButton.addEventListener('click', closeNotification); // 自动关闭提示框的定时器 setTimeout(() => { if (notification.style.display !== 'none') { closeNotification(); } }, 30000); // 30秒后自动关闭 } else { // 自动关闭提示框 setTimeout(closeNotification, autoCloseAfter * 1000); // 自动关闭时间(毫秒) } } // 加载所有懒加载的图片 function loadLazyImages() { // 选择所有带有 data-src 属性的图片 const lazyImages = document.querySelectorAll('img[data-src]'); lazyImages.forEach(img => { const src = img.getAttribute('data-src'); if (src) { img.src = src; // 将 data-src 的值赋给 src 属性 img.removeAttribute('data-src'); // 可选:移除 data-src 属性 } }); } // 加载所有懒加载的背景图片 function loadLazyBackgrounds() { const lazyBackgrounds = document.querySelectorAll('[data-background], [data-bg]'); lazyBackgrounds.forEach(element => { const bg = element.getAttribute('data-background') || element.getAttribute('data-bg'); if (bg) { element.style.backgroundImage = `url(${bg})`; // 将 data-background 或 data-bg 的值赋给 backgroundImage 样式 element.removeAttribute('data-background'); // 可选:移除 data-background 属性 element.removeAttribute('data-bg'); // 可选:移除 data-bg 属性 } }); } // 初始化懒加载 function load_image() { // 加载图片和背景图片 loadLazyImages(); loadLazyBackgrounds(); // 可选:观察 DOM 的变化以处理动态添加的内容 const observer = new MutationObserver(() => { loadLazyImages(); loadLazyBackgrounds(); }); observer.observe(document.body, { childList: true, subtree: true }); } // 初始化函数 function init() { load_image(); //加载所有懒加载的图片 addStyles(); //添加样式 checkCurrentUrl(); //检查当前网址是否在urlList中 addFloatingButton();//添加悬浮图片按钮 } // 执行初始化函数 init(); })();