您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
popup and hover zoom pan scroll any image on any website
当前为
// ==UserScript== // @name Hover Zoom Minus -- // @namespace Hover Zoom Minus -- // @version 1.0 // @description popup and hover zoom pan scroll any image on any website // @author Ein, with help from Copilot AI // @match *://*/* // @license MIT // @grant none // ==/UserScript== // 1. to use hover over the image(container) to view a popup of the target image // 2. to zoom in/out use wheel up/down. to reset press the scroll button // 3. click left mouse to lock popup this will follow the mouse, click again to release // 4. while locked the wheel up/down will act as scroll up/down // 5. to turn on/off hover at the bottom of the page // 6. easy to configure (function() { 'use strict'; // Configuration ---------------------------------------------------------- // Define your list of sites you want HoverZoomMinus to run with, // 1st array value - 1 will default it to turn on, 0 defaults it to turn off // 2nd array value - "center" to always spawn it in center otherwise '' [blank] spawns near the mouse // 3rd array value - allowed interval between respawing of popup. ie when exited on popup but imedietly touches an img container thus making it blinks or unsuable const siteList = { /*---- reddit */ 'new.reddit.com': [1, 'center','0'], /*------ 9gag */ '9gag.com': [1, 'center', '100'], /*---- feedly */ 'feedly.com': [1, 'center', '200'], /*----- 4chan */ 'boards.4chan.org': [1, '', '400'], /* deviantart */ 'www.deviantart.com': [0, 'center', '300'], }; // image container [hover area that triggers the popup] const imgContainers = ` /* --- reddit */ ._3Oa0THmZ3f5iZXAQ0hBJ0k > div, ._35oEP5zLnhKEbj5BlkTBUA, ._1ti9kvv_PMZEF2phzAjsGW > div, ._28TEYBuEdOuE3kN6UyoKMa div, ._3Oa0THmZ3f5iZXAQ0hBJ0k.WjuR4W-BBrvdtABBeKUMx div, /* ----- 9gag */ .post-container .post-view > picture, /* --- feedly */ .PinableImageContainer, .entryBody, /* ---- 4chan */ div.post div.file a, /* deviantart */ ._3_LJY, ._2e1g3, ._2SlAD `; // target img const imgElements = ` /* --- reddit */ ._2_tDEnGMLxpM6uOa2kaDB3, ._1dwExqTGJH2jnA-MYGkEL-, /* ----- 9gag */ .post-container .post-view > picture > img, /* --- feedly */ .pinable, .entryBody img, /* ---- 4chan */ div.post div.file img:nth-child(2), div.post div.file img:nth-child(1), ._3Oa0THmZ3f5iZXAQ0hBJ0k.WjuR4W-BBrvdtABBeKUMx img, /* deviantart */ ._3_LJY img._2e1g3 img, ._2SlAD img `; // excluded element const nopeElements = ` /* ------- reddit */ ._2ED-O3JtIcOqp8iIL1G5cg `; //------------------------------------------------------------------------- // The HoverZoomMinus Function--------------------------------------------- function HoverZoomMinus() { // Style for the popup image const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` .popup-image { max-height: calc(90vh - 10px); z-index: 1000; display: none; cursor: move;}`; document.head.appendChild(style); // Creating the popup image and backdrop const popup = document.createElement('img'); popup.className = 'popup-image'; document.body.appendChild(popup); const backdrop = document.createElement('div'); backdrop.className = 'popup-backdrop'; backdrop.style.cssText = ` position: fixed; top: 0; left: 0; width: 100 vw; height: 100 vh; display: none;`; document.body.appendChild(backdrop); //------------------------------------------------------------------------- // Function to show the popup function showPopup(src, mouseX, mouseY) { popup.src = src; popup.style.display = 'block'; popup.style.position = 'fixed'; popup.style.transform = 'translate(-50%, -50%)'; backdrop.style.display = 'block'; backdrop.style.zIndex = '999'; backdrop.style.backdropFilter = 'blur(10px)'; const currentDomain = window.location.hostname; const position = siteList[currentDomain] ? siteList[currentDomain][1] : ''; if (position === 'center') { popup.style.top = '50%'; popup.style.left = '50%'; } else { popup.style.top = `${mouseY}px`; popup.style.left = `${mouseX}px`; } } //------------------------------------------------------------------------- // Function combined Zoom and pan let isPanning = false; let offsetX, offsetY; let scale = 1; const ZOOM_SPEED = 0.005; popup.addEventListener('click', function(event) { isPanning = !isPanning; if (isPanning) { let rect = popup.getBoundingClientRect(); offsetX = event.clientX - rect.left - (rect.width / 2); offsetY = event.clientY - rect.top - (rect.height / 2); } }); document.addEventListener('mousemove', function(event) { if (isPanning) { popup.style.left = (event.clientX - offsetX) + 'px'; popup.style.top = (event.clientY - offsetY) + 'px'; } }); function zoomOrPan(event) { event.preventDefault(); if (isPanning) { let deltaY = event.deltaY * -ZOOM_SPEED; let newTop = parseInt(popup.style.top) || 0; newTop += deltaY * 100; popup.style.top = newTop + 'px'; offsetY -= deltaY * 100; } else { scale += event.deltaY * -ZOOM_SPEED; scale = Math.min(Math.max(0.125, scale), 4); popup.style.transform = `translate(-50%, -50%) scale(${scale})`; } } popup.addEventListener('wheel', zoomOrPan); //------------------------------------------------------------------------- // Function to show popup let popupTimer; document.addEventListener('mouseover', function(e) { if (popupTimer) return; let target = e.target.closest(imgContainers); if (!target) return; if (target.querySelector(nopeElements)) return; let currentContainer = target; const imageElement = currentContainer.querySelector(imgElements); if (imageElement) { const currentDomain = window.location.hostname; const domainConfig = siteList[currentDomain]; const position = siteList[currentDomain] ? siteList[currentDomain][1] : ''; const delayTimer = domainConfig ? domainConfig[2] : ''; if (delayTimer === '') { if (position === 'center') { showPopup(imageElement.src); } else { showPopup(imageElement.src, e.clientX, e.clientY); } } else { popupTimer = setTimeout(() => { if (position === 'center') { showPopup(imageElement.src); } else { showPopup(imageElement.src, e.clientX, e.clientY); } popupTimer = null; }, parseInt(delayTimer)); } } }); //------------------------------------------------------------------------- // Function to hide popup function hidePopup() { if (popupTimer) { clearTimeout(popupTimer); } document.body.appendChild(backdrop); popup.style.display = 'none'; popup.style.left = '50%'; popup.style.top = '50%'; popup.style.position = 'fixed'; popup.style.transform = 'translate(-50%, -50%) scale(1)'; backdrop.style.zIndex = ''; backdrop.style.display = 'none'; backdrop.style.backdropFilter = ''; isPanning = false; } document.addEventListener('mouseout', function(e) { let target = e.target.closest('.imgContainers'); let relatedTarget = e.relatedTarget; if (target && (!relatedTarget || (!relatedTarget.matches('.popup-image') && !relatedTarget.closest('.imgContainers')))) { hidePopup(); const currentDomain = window.location.hostname; const delayTimer = siteList[currentDomain] ? siteList[currentDomain][2] : ''; if (delayTimer !== '') { popupTimer = setTimeout(() => { popupTimer = null; }, parseInt(delayTimer)); } } }); popup.addEventListener('mouseout', function() { hidePopup(); const currentDomain = window.location.hostname; const delayTimer = siteList[currentDomain] ? siteList[currentDomain][2] : ''; if (delayTimer !== '') { popupTimer = setTimeout(() => { popupTimer = null; }, parseInt(delayTimer)); } }); document.addEventListener('keydown', function(event) { if (event.key === "Escape") { event.preventDefault(); hidePopup(); } }); } //------------------------------------------------------------------------- // Is HoverZoomMinus to be run const indicatorBar = document.createElement('div'); indicatorBar.style.cssText = ` position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); z-index: 9999; height: 30px; width: 50vw; background: #0000;`; document.body.appendChild(indicatorBar); function toggleIndicator() { indicatorValue = 1 - indicatorValue; indicatorBar.style.background = indicatorValue ? 'rgba(50, 190, 152, 0.5)' : 'rgba(174, 0, 1, 0.5)'; setTimeout(() => { indicatorBar.style.background = '#0000'; }, 1000); if (indicatorValue === 1) { HoverZoomMinus(); } else { const existingPopup = document.body.querySelector('.popup-image'); if (existingPopup) document.body.removeChild(existingPopup); const existingBackdrop = document.body.querySelector('.popup-backdrop'); if (existingBackdrop) document.body.removeChild(existingBackdrop); } } let indicatorValue; const currentDomain = window.location.hostname; if (siteList.hasOwnProperty(currentDomain)) { indicatorValue = siteList[currentDomain][0]; let hoverTimeout; indicatorBar.addEventListener('mouseenter', () => { hoverTimeout = setTimeout(toggleIndicator, 500); }); indicatorBar.addEventListener('mouseleave', () => { clearTimeout(hoverTimeout); indicatorBar.style.background = '#0000'; }); if (indicatorValue === 1) { HoverZoomMinus(); } } else { return; } })();