您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
image popup: zoom, pan, scroll, pin, scale
当前为
// ==UserScript== // @name Hover Zoom Minus -- // @namespace Hover Zoom Minus -- // @version 1.0.9.4 // @description image popup: zoom, pan, scroll, pin, scale // @author Ein, Copilot AI // @match *://*/* // @license MIT // @grant none // ==/UserScript== // 01. to use hover over the image(container) to view a popup of the target image // 02. to zoom in/out use wheel up/down. // 03. click left mouse to lock popup this will make it move along with the mouse, click again to release (indicated by green border) // 04. while being locked"Y" the wheel up/down will act as scroll up/down // 05. double click will lock it on screen preventing it from being hidden // 06. hover below the image and click blue bar this will make a 3rd mode for wheel bottom, which will scroll next/previous image under an album // 07. while locked at screen (indicated by red outline) a single click with the blurred background will unblur it, only one popup per time, so the locked popup will prevent other popup to spawn // 08. double clicking on blurred background will de-spawn popup // 09. click on the corner to toggle scaling (blue) will retain current aspect ratio, double clicking will turn to 2nd mode for scaling (magenta) will not retain current aspect ratio // 10. return to original aspect ration via clicking on sides, if it's in an album to reset to aspect ratio on bottom side use double click // 11. you can now crop and save the image, just double click the top to initiate. // 12. to turn on/off hover at the bottom of the page (function() { 'use strict'; // Configuration ---------------------------------------------------------- // Define regexp of web page you want HoverZoomMinus to run with, // 1st array value - default status at start of page: '1' for on, '0' for off // 2nd array value - spawn position for popup: 'center' for center of screen, '' for cursor position // 3rd array value - allowed interval for spawning popup; i.e. when exited on popup but immediately touches an img container thus making it "blink spawn blink spawn", experiment it with the right number const siteConfig = { 'reddit.com': [1, 'center', '100'], '9gag.com': [1, 'center', '0'], 'feedly.com': [1, 'center', '200'], '4chan.org': [1, '', '400'], 'deviantart.com': [0, 'center', '300'], 'home': [1, 'center', '0'] /* for testing */ }; // image container [hover box where popup triggers] const imgContainers = ` /* ------- reddit */ ._3BxRNDoASi9FbGX01ewiLg, ._3Oa0THmZ3f5iZXAQ0hBJ0k > div, ._35oEP5zLnhKEbj5BlkTBUA, ._1ti9kvv_PMZEF2phzAjsGW > div, /* ------- reddit */ ._28TEYBuEdOuE3kN6UyoKMa div, ._3Oa0THmZ3f5iZXAQ0hBJ0k.WjuR4W-BBrvdtABBeKUMx div, ._3m20hIKOhTTeMgPnfMbVNN, zoomable-img.fixed, /* --------- 9gag */ .post-container .post-view > picture, /* ------- feedly */ .PinableImageContainer, .entryBody, /* -------- 4chan */ div.post div.file a, /* --- deviantart */ ._3_LJY, ._2e1g3, ._2SlAD, ._1R2x6 `; // target img const imgElements = ` /* ------- reddit */ ._2_tDEnGMLxpM6uOa2kaDB3, ._1dwExqTGJH2jnA-MYGkEL-, ._2_tDEnGMLxpM6uOa2kaDB3._1XWObl-3b9tPy64oaG6fax, zoomable-img.fixed img, /* --------- 9gag */ .post-container .post-view > picture > img, /* ------- feedly */ .pinable, .entryBody img, /* -------- 4chan */ div.post div.file img:nth-child(1), ._3Oa0THmZ3f5iZXAQ0hBJ0k.WjuR4W-BBrvdtABBeKUMx img, div.post div.file .fileThumb img, /* --- deviantart */ ._3_LJY img, ._2e1g3 img, ._2SlAD img, ._1R2x6 img `; // excluded element const nopeElements = ` /* ------- reddit */ ._2ED-O3JtIcOqp8iIL1G5cg `; // AlbumSelector take note that it will only load image that are already in the DOM tree // example reddit will not include all until you press navigator buttons so most of the time this will only load a few image // unless you update it via interacting with navigator button thus updating the DOM tree (added new function for navigation it can now update) let albumSelector = [ /* ---reddit */ { imgElement: '._1dwExqTGJH2jnA-MYGkEL-', albumElements: '._1apobczT0TzIKMWpza0OhL' }, /* ---feedly */ { imgElement: '.entryBody > div > img', albumElements: '.entryBody > div' }, /* ---feedly */ { imgElement: 'div[id^="Article-"] > div > span > img', albumElements: 'div[id^="Article-"]' }, ]; // specialElements were if targeted, will call it's paired function // for convenience an element className "specialElement" will be remove during mouseout or function hidepopup() is called you can use that with specialElements function for temporary elements const specialElements = [ /* --- 4chan */ { selector: 'div.post div.file .fileThumb img', func: SP1 }, /* -- reddit */ { selector: '._1dwExqTGJH2jnA-MYGkEL-', func: SP2 } ]; // special function triggered when clicking LeftBar/ wheel down in album mode const specialLeftBar = [ /* -- reddit */ { selector: '._1dwExqTGJH2jnA-MYGkEL-', func: SPL } ]; // special function triggered when clicking RightBar/ wheel up in album mode const specialRightBar = [ /* -- reddit */ { selector: '._1dwExqTGJH2jnA-MYGkEL-', func: SPR } ]; //------------------------------------------------------------------------- // Special Funtions ------------------------------------------------------- // 4chan: replaces thumbnail so popup will use the larger version, or if its animated replace it with that function SP1(imageElement) { const parentElement = imageElement.parentElement; const href = parentElement.getAttribute('href'); if (parentElement.tagName === 'a') { if (href.endsWith('.webm')) { const videoElement = document.createElement('video'); videoElement.src = href; videoElement.controls = true; parentElement.replaceChild(videoElement, imageElement); } else { imageElement.setAttribute('src', href); } } else { imageElement.setAttribute('src', href); } } // reddit: added the label/description of image along with the popup function SP2(imageElement) { if (enableP === 0) { return; } let closestElement = imageElement.closest('.m3aNC6yp8RrNM_-a0rrfa, .kcerW9lbT-se3SXd-wp2i'); if (!closestElement) { return; } let descendantElement = closestElement.querySelector('._15nNdGlBIgryHV04IfAfpA'); if (descendantElement) { document.querySelectorAll('.specialElement').forEach(e => e.remove()); let title = descendantElement.getAttribute('title'); const specialContent = document.createElement('div'); specialContent.className = 'specialElement'; specialContent.style.cssText = 'position:fixed; bottom:80px; left:50%; transform:translateX(-50%); width:100vw; text-align:center; font-size:40px; color:white; text-shadow:0 0 10px rgba(255,255,255,0.7); z-index:99999;'; specialContent.textContent = title; document.body.appendChild(specialContent); var specialBackdrop = document.createElement('div'); specialBackdrop.className = 'specialElement'; specialBackdrop.style.cssText = 'position:fixed; bottom:60px; left:0; width:100vw; height:80px; background:rgba(0,0,0,0.2); backdrop-filter:blur(5px); z-index:99998;'; document.body.appendChild(specialBackdrop); } else { return; } } function SPL(imageElement) { document.querySelectorAll('.specialElement').forEach(e => e.remove()); let closestElement = imageElement.closest('.kcerW9lbT-se3SXd-wp2i'); var element = closestElement.querySelector('._1fSFPkxZ9pToLETLQT2dmc'); if (element) element.click(); let descendantElement = closestElement.querySelector('._15nNdGlBIgryHV04IfAfpA'); if (descendantElement) { let title = descendantElement.getAttribute('title'); const specialContent = document.createElement('div'); specialContent.className = 'specialElement'; specialContent.style.cssText = 'position:fixed; bottom:80px; left:50%; transform:translateX(-50%); width:100vw; text-align:center; font-size:40px; color:white; text-shadow:0 0 10px rgba(255,255,255,0.7); z-index:99999;'; specialContent.textContent = title; document.body.appendChild(specialContent); var specialBackdrop = document.createElement('div'); specialBackdrop.className = 'specialElement'; specialBackdrop.style.cssText = 'position:fixed; bottom:60px; left:0; width:100vw; height:80px; background:rgba(0,0,0,0.2); backdrop-filter:blur(5px); z-index:99998;'; document.body.appendChild(specialBackdrop); } else { return; } } function SPR(imageElement) { document.querySelectorAll('.specialElement').forEach(e => e.remove()); let closestElement = imageElement.closest('.kcerW9lbT-se3SXd-wp2i'); var element = closestElement.querySelector('._3-JCOd-nY76g29C7ZVX_kl:last-child'); if (element) element.click(); let descendantElement = closestElement.querySelector('._15nNdGlBIgryHV04IfAfpA'); if (descendantElement) { let title = descendantElement.getAttribute('title'); const specialContent = document.createElement('div'); specialContent.className = 'specialElement'; specialContent.style.cssText = 'position:fixed; bottom:80px; left:50%; transform:translateX(-50%); width:100vw; text-align:center; font-size:40px; color:white; text-shadow:0 0 10px rgba(255,255,255,0.7); z-index:99999;'; specialContent.textContent = title; document.body.appendChild(specialContent); var specialBackdrop = document.createElement('div'); specialBackdrop.className = 'specialElement'; specialBackdrop.style.cssText = 'position:fixed; bottom:60px; left:0; width:100vw; height:80px; background:rgba(0,0,0,0.2); backdrop-filter:blur(5px); z-index:99998;'; document.body.appendChild(specialBackdrop); } else { return; } } //------------------------------------------------------------------------- // Configuration variables const currentHref = window.location.href; let enableP, positionP, intervalP, URLmatched; Object.keys(siteConfig).some((config) => { const regex = new RegExp(config); if (currentHref.match(regex)) { [enableP, positionP, intervalP] = siteConfig[config]; URLmatched = true; return true; } }); // The HoverZoomMinus Function--------------------------------------------- function HoverZoomMinus() { let isshowPopupEnabled = true; isshowPopupEnabled = true; const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` .popup-container { display:none; cursor: move; z-index:1001; } .popup-image { max-height:calc(90vh - 10px); display:none; } .popup-backdrop { position:fixed; top:0; left:0; width:100vw; height:100vh; display:none; z-index:1000; } .centerBox { top:40px; left:40px; position:absolute; height:calc(100% - 80px); width:calc(100% - 80px); z-index:9999; } .TopBar, .BottomBar, .LeftBar, .RightBar { opacity:0; box-sizing:border-box; background:#0000; position:absolute; z-index:9999; &::after { content:""; position:absolute; } } .TopBar, .BottomBar { height:40px; width:calc(100% - 80px); left:40px; &::after { display:none; width:25px; height:25px; transform:rotate(45deg) translateX(-50%) translateY(-50%); } } .TopBar { top:0; } .BottomBar { bottom:0; } .TopBar::after { left:calc(50% - 17px); top:calc(50% + 15px); border-top:5px solid #6f8e9e; border-left:5px solid #6f8e9e; } .BottomBar::after { left:calc(50% - 2px); bottom:-8px; border-bottom:5px solid #6f8e9e; border-right: 5px solid #6f8e9e; } .LeftBar, .RightBar { height:calc(100% - 80px); width:40px; top:40px; &::before { content:""; display:block; position:absolute; top:50%; width:40px; height:40px; transform:translateY(-50%); border-radius:9999px; background: #242526; } &::after { content:""; display:block; position:absolute; top:calc(50% + -2px); width:15px; height:15px; } &:hover::before { display:none; } &:hover::after { width:25px; height:25px; border-color:#6f8e9e; border-width:5px; } } .LeftBar { left:0; } .RightBar { right:0; } .LeftBar::before { left:5px; } .RightBar::before { right:5px; } .LeftBar:hover::after { left:3px; } .RightBar:hover::after { right:3px; } .LeftBar::after { transform:rotate(45deg) translateY(-50%); border-bottom:3px solid #777; border-left:3px solid #777; left:12px; } .RightBar::after { transform:rotate(-45deg) translateY(-50%); border-bottom: 3px solid #777; border-right:3px solid #777; right:12px; } .CornerBox { box-sizing:border-box; height:40px; width:40px; background:#0000; position:absolute; z-index:9999; } .CornerBox.TR { top:0; right:0; font-size:11px; text-align:center; line-height:25px; color:white; text-shadow:0 0 4px rgba(255,255,255,0.7); } .CornerBox.TL { top:0; left:0; } .CornerBox.BR { bottom:0; right:0; } .CornerBox.BL { bottom:0; left:0;} `; document.head.appendChild(style); const backdrop = document.createElement('div'); backdrop.className = 'popup-backdrop'; document.body.appendChild(backdrop); const popupContainer = document.createElement('div'); popupContainer.className = 'popup-container'; document.body.appendChild(popupContainer); const popup = document.createElement('img'); popup.className = 'popup-image'; popupContainer.appendChild(popup); const BottomBar = document.createElement('div'); BottomBar.className = 'BottomBar'; popupContainer.appendChild(BottomBar); const TopBar = document.createElement('div'); TopBar.className = 'TopBar'; popupContainer.appendChild(TopBar); const RightBar = document.createElement('div'); RightBar.className = 'RightBar'; popupContainer.appendChild(RightBar); const LeftBar = document.createElement('div'); LeftBar.className = 'LeftBar'; popupContainer.appendChild(LeftBar); const TR = document.createElement('div'); TR.className = 'CornerBox TR'; popupContainer.appendChild(TR); const TL = document.createElement('div'); TL.className = 'CornerBox TL'; popupContainer.appendChild(TL); const BR = document.createElement('div'); BR.className = 'CornerBox BR'; popupContainer.appendChild(BR); const BL = document.createElement('div'); BL.className = 'CornerBox BL'; popupContainer.appendChild(BL); const centerBox = document.createElement('div'); centerBox.className = 'popup centerBox'; popupContainer.appendChild(centerBox); const style2 = document.createElement('style'); style2.type = 'text/css'; document.head.appendChild(style2); //------------------------------------------------------------------------- // Variable const ZOOM_SPEED = 0.005; let pageDirection; let isLockedY = false; let isLockedX = false; let scale = 1; let clickTimeout; let popupTimer; let isScale, isScaleTR, isScaleBR, isScaleTL, isScaleBL; let rect, rectT, rectH, rectL, rectW; let rectIH, rectIW, rectIT, rectIL, rectIRatio; let rectzT, rectzH, rectzL, rectzW, rectzRatio; let scaleCurrentX, scaleCurrentY; let scaleFactorX, scaleFactorY; let offsetX, offsetY, offsetXR, offsetYT, offsetXL, offsetYB; let offsetRatioY, offsetRatioX; let ishidePopupEnabled = true; let ScaleMode2 = false; let imgElementsList = []; let currentZeroImgElement; let rectIzRatio; function NoMode() { isLockedY = false; isLockedX = false; isScale = false; isScaleTR = false; isScaleTL = false; isScaleBL = false; isScaleBR = false; popupContainer.style.border = ''; TR.style.border = ''; BR.style.border = ''; TL.style.border = ''; BL.style.border = ''; } function LockedYMode() { NoMode(); isLockedY = true; popupContainer.style.borderLeft = '6px solid #00ff00'; popupContainer.style.borderRight = '6px solid #00ff00'; LeftBar.style.opacity = '0'; RightBar.style.opacity = '0'; LeftBar.style.display = ''; RightBar.style.display = ''; } function LockedXMode() { NoMode(); LockedScreen(); isLockedX = true; popupContainer.style.borderTop = '6px solid #00ff00'; popupContainer.style.borderBottom = '6px solid #00ff00'; LeftBar.style.opacity = '1'; RightBar.style.opacity = '1'; style2.innerHTML = ` .LeftBar::before, .LeftBar::after, .RightBar::before, .RightBar::after { display: block; } `; } function toggleLockedScreen(event) { ishidePopupEnabled = !ishidePopupEnabled; popupContainer.style.outline = ishidePopupEnabled ? '' : '6px solid #ae0001'; } function LockedScreen() { ishidePopupEnabled = false; popupContainer.style.outline = '6px solid #ae0001'; } function ScalingMode1() { TL.style.borderTop = '6px solid #0000ff'; TR.style.borderTop = '6px solid #0000ff'; TL.style.borderLeft = '6px solid #0000ff'; BL.style.borderLeft = '6px solid #0000ff'; TR.style.borderRight = '6px solid #0000ff'; BR.style.borderRight = '6px solid #0000ff'; BR.style.borderBottom = '6px solid #0000ff'; BL.style.borderBottom = '6px solid #0000ff'; } function ScalingMode2() { ScalingMode1(); TL.style.borderColor = '#ff00ff'; TR.style.borderColor = '#ff00ff'; BL.style.borderColor = '#ff00ff'; BR.style.borderColor = '#ff00ff'; } function ScalingMode0() { TL.style.border = ''; TR.style.border = ''; BL.style.border = ''; BR.style.border = ''; } function ResetGeometry() { let rectF = popup.getBoundingClientRect(); rectzH = rectF.height; rectzW = rectF.width; rectzT = rectF.top; rectzL = rectF.left; popup.style.maxHeight = rectzH + 'px'; popup.style.height = rectzH + 'px'; popup.style.width = rectzW + 'px'; popupContainer.style.top = rectzT + (rectzH / 2) + 'px'; popupContainer.style.left = rectzL + (rectzW / 2) + 'px'; popupContainer.style.transformOrigin = '50% 50% 0px'; popupContainer.style.transform = `translate(-50%, -50%) scaleX(1) scaleY(1)`; } function BarClear() { TL.style.border = ''; TR.style.border = ''; BL.style.border = ''; BR.style.border = ''; TL.style.background = ''; TR.style.background = ''; BL.style.background = ''; BR.style.background = ''; TopBar.style.background = ''; LeftBar.style.background = ''; RightBar.style.background = ''; BottomBar.style.background = ''; popupContainer.style.border = ''; LeftBar.style.opacity = '0'; RightBar.style.opacity = '0'; } function NavigateAlbum() { let pair = albumSelector.find(pair => currentZeroImgElement.matches(pair.imgElement)); if (pair) { let ancestorElement = currentZeroImgElement.closest(pair.albumElements); if (ancestorElement) { imgElementsList = Array.from(ancestorElement.querySelectorAll(pair.imgElement)); let zeroIndex = imgElementsList.indexOf(currentZeroImgElement); let direction = pageDirection; let newIndex = zeroIndex + direction; TR.textContent = `${newIndex + 1}/${imgElementsList.length}`; if (newIndex <= 0) { LeftBar.style.display = 'none'; TR.textContent = `1/${imgElementsList.length}`; } else { LeftBar.style.display = ''; } if (newIndex >= imgElementsList.length - 1) { RightBar.style.display = 'none'; TR.textContent = `${imgElementsList.length}/${imgElementsList.length}`; } else { RightBar.style.display = ''; } if (newIndex < 0 || newIndex >= imgElementsList.length) { return; } currentZeroImgElement = imgElementsList[newIndex]; var img = new Image(); img.onload = function() { let natHeight = img.naturalHeight; let vh = window.innerHeight / 100; if (natHeight > ((90 * vh) - 10)) { popup.style.maxHeight = (90 * vh) - 10 + 'px'; popup.style.width = ''; popupContainer.style.top = '50%'; } else { popup.style.height = ''; popup.style.maxHeight = 'unset'; } }; popup.src = currentZeroImgElement.src; img.src = popup.src; } } } // Mouse Click: Center centerBox.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { ResetGeometry(); if (!isScale) { isLockedY = !isLockedY; } if (isLockedY) { LockedYMode(); let rect = popupContainer.getBoundingClientRect(); offsetX = event.clientX - rect.left - (rect.width / 2); offsetY = event.clientY - rect.top - (rect.height / 2); } else { NoMode(); } }, 300); }); centerBox.addEventListener('dblclick', function(event) { clearTimeout(clickTimeout); toggleLockedScreen(); if (!ishidePopupEnabled) { backdrop.style.display = 'block'; backdrop.style.zIndex = '999'; backdrop.style.backdropFilter = 'blur(10px)'; } }); //------------------------------------------------------------------------- // Mouse Click: Corners // Mouse Click: Corners document.querySelectorAll('.CornerBox').forEach(element => { element.addEventListener('click', function(event) { ishidePopupEnabled = false; if (isScale) { BarClear(); isLockedY = false; isLockedX = false; popup.style.border = ''; const clickedElement = event.target; const popupContainer = clickedElement.parentElement; const currentTransform = window.getComputedStyle(popupContainer).transform; const matrixMatch = currentTransform.match(/^matrix\(([^,]+), [^,]+, [^,]+, ([^,]+), [^,]+, [^,]+\)$/); if (matrixMatch) { scaleCurrentX = parseFloat(matrixMatch[1]); scaleCurrentY = parseFloat(matrixMatch[2]); } let rect = popupContainer.getBoundingClientRect(); offsetYT = event.clientY - rect.top; offsetXL = event.clientX - rect.left; offsetYB = rect.height + rect.top - event.clientY; offsetXR = rect.width + rect.left - event.clientX; rectT = rect.top; rectL = rect.left; rectH = rect.height; rectW = rect.width; } else { LockedScreen(); ResetGeometry(); } }); }); document.querySelectorAll('.CornerBox').forEach(element => { element.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); isScale = !isScale; }, 300); }); document.querySelectorAll('.CornerBox').forEach(element => { element.addEventListener('dblclick', function(event) { clearTimeout(clickTimeout); ScaleMode2 = !ScaleMode2; }); }); TL.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { isScaleTL = !isScaleTL; isScaleTR = false; isScaleBL = false; isScaleBR = false; LeftBar.style.display = ''; RightBar.style.display = ''; }, 300); }); TR.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { isScaleTL = false; isScaleTR = !isScaleTR; isScaleBL = false; isScaleBR = false; LeftBar.style.display = ''; RightBar.style.display = ''; }, 300); }); BL.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { isScaleTL = false; isScaleTR = false; isScaleBL = !isScaleBL; isScaleBR = false; LeftBar.style.display = ''; RightBar.style.display = ''; }, 300); }); BR.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { isScaleTL = false; isScaleTR = false; isScaleBL = false; isScaleBR = !isScaleBR; LeftBar.style.display = ''; RightBar.style.display = ''; }, 300); }); //------------------------------------------------------------------------- // Mouse Move: Pan, Scale document.addEventListener('mousemove', function(event) { // Panning mode: popup locked and follows the mouse if (isLockedY) { popupContainer.style.left = (event.clientX - offsetX) + 'px'; popupContainer.style.top = (event.clientY - offsetY) + 'px'; } else if (isScale) { ScalingMode1(); if (ScaleMode2) { ScalingMode2(); } if (isScaleTL) { popupContainer.style.transformOrigin = '100% 100% 0px'; scaleFactorY = scaleCurrentY * (1 + (rectT - event.clientY + offsetYT) / rectH); scaleFactorX = scaleCurrentX * (1 + (rectL - event.clientX + offsetXL) / rectW); } else if (isScaleTR) { popupContainer.style.transformOrigin = '0 100% 0px'; scaleFactorY = scaleCurrentY * (1 + (rectT - event.clientY + offsetYT) / rectH); scaleFactorX = scaleCurrentX * ((event.clientX - rectL + offsetXR) / rectW); } else if (isScaleBL) { popupContainer.style.transformOrigin = '100% 0% 0px'; scaleFactorY = scaleCurrentY * ((event.clientY - rectT + offsetYB) / rectH); scaleFactorX = scaleCurrentX * (1 + (rectL - event.clientX + offsetXL) / rectW); } else if (isScaleBR) { popupContainer.style.transformOrigin = '0% 0% 0px'; scaleFactorY = scaleCurrentY * ((event.clientY - rectT + offsetYB) / rectH); scaleFactorX = scaleCurrentX * ((event.clientX - rectL + offsetXR) / rectW); } if (ScaleMode2) { popupContainer.style.transform = `translate(-50%, -50%) scaleX(${scaleFactorX}) scaleY(${scaleFactorY})`; } else { popupContainer.style.transform = `translate(-50%, -50%) scaleX(${scaleFactorX}) scaleY(${scaleFactorX})`; } } }); // Mouse Wheel: Zoom, Scroll, Navigate function ZoomOrScroll(event) { event.preventDefault(); if (isLockedY) { let deltaY = event.deltaY * -ZOOM_SPEED; let newTop = parseInt(popupContainer.style.top) || 0; newTop += deltaY * 100; popupContainer.style.top = newTop + 'px'; offsetY -= deltaY * 100; } else if (isLockedX && currentZeroImgElement) { pageDirection = event.deltaY > 0 ? 1 : -1; NavigateAlbum(); if (pageDirection === 1) { const imageElement = currentContainer.querySelector(imgElements); specialRightBar.forEach(pair => { if (imageElement.matches(pair.selector)) { pair.func(imageElement); } }); } else { const imageElement = currentContainer.querySelector(imgElements); specialLeftBar.forEach(pair => { if (imageElement.matches(pair.selector)) { pair.func(imageElement); } }); } } else { scale += event.deltaY * -ZOOM_SPEED; scale = Math.min(Math.max(0.125, scale), 10); popupContainer.style.transform = `translate(-50%, -50%) scaleX(${scale}) scaleY(${scale})`; } } popupContainer.addEventListener('wheel', ZoomOrScroll); //------------------------------------------------------------------------- // Bottom Bar: Album BottomBar.addEventListener('mouseenter', function(e) { if (isScale) { return; } else { BottomBar.style.opacity = '1'; let rect = popup.getBoundingClientRect(); rectzRatio = rect.height / rect.width; rectIzRatio = Number(rectIRatio.toFixed(3)) / Number(rectzRatio.toFixed(3)); if (isAlbum) { if (!isScale) { BottomBar.style.background = 'linear-gradient(to right, rgba(0, 0, 255, 0) 0%, rgba(0, 0, 255, 0.5) 25%, rgba(0, 0, 255, 0.5) 75%, rgba(0, 0, 255, 0) 100%)'; } } else { BottomBar.style.background = ''; if (!( (rectIzRatio === 1) || isScale ) ) { style2.innerHTML = ` .BottomBar::after { display: block; } `; BL.style.background = 'rgba(0, 0, 0, 0.5)'; BR.style.background = 'rgba(0, 0, 0, 0.5)'; BottomBar.style.background = 'rgba(0, 0, 0, 0.5)'; } else { style2.innerHTML = ` .BottomBar::after { display: none; } `; } } } }); BottomBar.addEventListener('mouseleave', function() { BottomBar.style.opacity = '0'; if (!isLockedX) { BarClear(); } }); BottomBar.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { if (!isScale) { LeftBar.style.opacity = '0'; RightBar.style.opacity = '0'; } if (isAlbum) { ResetGeometry(); var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src rectIRatio = natHeight / natWidth; isLockedX = !isLockedX; if (isLockedX) { LockedXMode(); LeftBar.style.opacity = '1'; RightBar.style.opacity = '1'; } else { popupContainer.style.border = ''; LeftBar.style.display = ''; RightBar.style.display = ''; } } else { ResetGeometry(); if (isScale) { isScale = false; popup.style.maxHeight = rectzH + 'px'; popup.style.height = rectzH + 'px'; offsetRatioY = 0; } else { popup.style.maxHeight = 'unset'; popup.style.height = ''; offsetRatioY = (rectzH - rectzW * rectIRatio) / 2 ; } popupContainer.style.top = rectzT + (rectzH / 2) + offsetRatioY + 'px'; } }, 300); }); BottomBar.addEventListener('dblclick', function(event) { clearTimeout(clickTimeout); if (isAlbum) { ResetGeometry(); var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src rectIRatio = natHeight / natWidth; if (isScale) { popup.style.maxHeight = rectzH + 'px'; popup.style.height = rectzH + 'px'; offsetRatioY = 0; } else { popup.style.maxHeight = 'unset'; popup.style.height = ''; offsetRatioY = (rectzH - rectzW * rectIRatio) / 2 ; } popupContainer.style.top = rectzT + (rectzH / 2) + offsetRatioY + 'px'; BarClear(); } else { return; } }); //------------------------------------------------------------------------- // Indicators document.querySelectorAll('.CornerBox').forEach(element => { element.addEventListener('mouseenter', function(event) { ScalingMode1(); if (ScaleMode2) { ScalingMode2(); } }); element.addEventListener('mouseleave', function(event) { if (!isScale) { ScalingMode0(); } }); }); // Re-scale/ Navigate TopBar.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { ResetGeometry(); if (isAlbum) { var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src rectIRatio = natHeight / natWidth; } if (isScale) { isScale = false; popup.style.maxHeight = rectzH + 'px'; popup.style.height = rectzH + 'px'; offsetRatioY = 0; } else { popup.style.maxHeight = 'unset'; popup.style.height = ''; offsetRatioY = (rectzH - rectzW * rectIRatio) / 2 ; } popupContainer.style.top = rectzT + (rectzH / 2) - offsetRatioY + 'px'; BarClear(); }, 300); }); const styleCrop = document.createElement('style'); styleCrop.type = 'text/css'; styleCrop.innerHTML = `.cropArea1,.cropArea2,.cropArea3,.cropArea4 { display:none; }`; const CropCover = document.createElement('div'); const cropArea1 = document.createElement('div'); const cropArea2 = document.createElement('div'); const cropArea3 = document.createElement('div'); const cropArea4 = document.createElement('div'); let clickX1, clickY1, clickX2, clickY2; let clickCount; let cropAreaSet = false; TopBar.addEventListener('dblclick', function(event) { clearTimeout(window.clickTimeout); LockedScreen(); clickCount = 0; ResetGeometry() cropAreaSet = false; const CropCover = document.createElement('div'); const cropArea1 = document.createElement('div'); const cropArea2 = document.createElement('div'); const cropArea3 = document.createElement('div'); const cropArea4 = document.createElement('div'); CropCover.className = 'CropCover' cropArea1.className = 'cropArea1'; cropArea2.className = 'cropArea2'; cropArea3.className = 'cropArea3'; cropArea4.className = 'cropArea4'; popupContainer.appendChild(CropCover); document.body.appendChild(cropArea1); document.body.appendChild(cropArea2); document.body.appendChild(cropArea3); document.body.appendChild(cropArea4); CropCover.style.cssText = 'position:absolute; transform:translateZ(0); top:0; left:0; box-sizing:border-box; height:100%; width:100%; z-index:99999; border:1px solid yellow;'; cropArea1.style.cssText ='display: block; z-index: 9999; position: fixed; background: rgba(0, 0, 0, 0.4);'; cropArea2.style.cssText ='display: block; z-index: 9999; position: fixed; background: rgba(0, 0, 0, 0.4);'; cropArea3.style.cssText ='display: block; z-index: 9999; position: fixed; background: rgba(0, 0, 0, 0.4);'; cropArea4.style.cssText ='display: block; z-index: 9999; position: fixed; background: rgba(0, 0, 0, 0.4);'; let rect = popup.getBoundingClientRect(); rectzH = rect.height; rectzW = rect.width; rectzT = rect.top; rectzL = rect.left; let clickTimeout; CropCover.addEventListener('click', function(e) { if (clickCount === 0) { clickX1 = e.clientX; clickY1 = e.clientY; clickCount = 1; } else if (clickCount === 1) { clickCount = 2; clickX2 = e.clientX; clickY2 = e.clientY; cropAreaSet = true; if (clickCount === 2) { cropImage(); } } }); document.addEventListener('mousemove', function(event) { cropArea1.style.left = '0px'; cropArea1.style.top = '0px'; cropArea1.style.height = '100vh'; cropArea2.style.top = '0px'; if (clickCount === 0) { cropArea1.style.width = event.clientX + 'px'; cropArea2.style.left = event.clientX + 'px'; cropArea2.style.height = event.clientY + 'px'; cropArea2.style.width = `calc(100vw - ${event.clientX}px)`; } else if (clickCount === 1) { cropArea1.style.width = clickX1 + 'px'; cropArea2.style.left = clickX1 + 'px'; cropArea2.style.height = clickY1 + 'px'; cropArea2.style.width = `calc(100vw - ${clickX1}px)`; } if (!cropAreaSet && (clickCount === 1)) { cropArea3.style.left = clickX1 + 'px'; cropArea3.style.top = event.clientY + 1 + 'px'; cropArea3.style.width = `calc(${event.clientX}px + 1px - ${clickX1}px)`; cropArea3.style.height = `calc(100vh - 1px - ${event.clientY}px)`; cropArea4.style.left = event.clientX + 1 + 'px'; cropArea4.style.top = clickY1 + 'px' cropArea4.style.height = `calc(100vh - 1px - ${clickY1}px)`; cropArea4.style.width = `calc(100vw - 1px - ${event.clientX}px)`; } }); }); function cropImage() { var canvas = document.createElement('canvas'); canvas.id = 'cropCanvas'; var ctx = canvas.getContext('2d'); document.body.appendChild(canvas); let cropX, cropY, cropW, cropH, scW, scH scW = clickX2 - clickX1 scH = clickY2 - clickY1 cropX = natWidth * ((clickX1 - rectzL) / rectzW); cropY = natHeight * ((clickY1 - rectzT) / rectzH); cropW = natWidth * (scW / rectzW); cropH = natHeight * (scH / rectzH); canvas.width = scW; canvas.height = scH; var image = new Image(); image.crossOrigin = "anonymous"; image.src = popup.src image.onload = function() { ctx.drawImage(image, cropX, cropY, cropW, cropH, 0, 0, scW, scH); saveImage(canvas); } document.querySelectorAll('.CropCover').forEach(e => e.remove()) } function saveImage(canvas) { if (confirm('Do you want to save the image?')) { var croppedImageDataURL = canvas.toDataURL('image/png'); var originalFileName = popup.src.split('/').pop(); var truncatedFileName = originalFileName.length > 100 ? originalFileName.substring(0, 100) : originalFileName; var downloadLink = document.createElement('a'); downloadLink.href = croppedImageDataURL; downloadLink.download = truncatedFileName; document.body.appendChild(downloadLink); downloadLink.click(); } clickCount = 0; cropAreaSet = false; document.querySelectorAll('.cropArea1').forEach(e => e.remove()) document.querySelectorAll('.cropArea2').forEach(e => e.remove()) document.querySelectorAll('.cropArea3').forEach(e => e.remove()) document.querySelectorAll('.cropArea4').forEach(e => e.remove()) document.body.removeChild(downloadLink); var removecropCanvas = document.getElementById('cropCanvas'); removecropCanvas.remove(); } let zeroIndex; LeftBar.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { ResetGeometry(); if (isAlbum) { var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src rectIRatio = natHeight / natWidth; } if (isScale) { isScale = false; popup.style.width = rectzW + 'px'; offsetRatioX = 0; } else { popup.style.width = ''; offsetRatioX = (rectzW - (rectzH / rectIRatio)) / 2 ; } if (isLockedX && currentZeroImgElement) { pageDirection = -1; NavigateAlbum(); TL.style.background = 'rgba(0, 0, 0, 0.5)'; BL.style.background = 'rgba(0, 0, 0, 0.5)'; LeftBar.style.background = 'rgba(0, 0, 0, 0.5)'; const imageElement = currentContainer.querySelector(imgElements); specialLeftBar.forEach(pair => { if (imageElement.matches(pair.selector)) { pair.func(imageElement); } }); } else { popupContainer.style.left = rectzL + (rectzW / 2) - offsetRatioX + 'px'; } }, 300); }); RightBar.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { ResetGeometry(); if (isAlbum) { var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src rectIRatio = natHeight / natWidth; } if (isScale) { isScale = false; popup.style.width = rectzW + 'px'; offsetRatioX = 0; } else { popup.style.width = ''; offsetRatioX = (rectzW - (rectzH / rectIRatio)) / 2 ; } if (isLockedX && currentZeroImgElement) { pageDirection = 1; NavigateAlbum(); TR.style.background = 'rgba(0, 0, 0, 0.5)'; BR.style.background = 'rgba(0, 0, 0, 0.5)'; RightBar.style.background = 'rgba(0, 0, 0, 0.5)'; const imageElement = currentContainer.querySelector(imgElements); specialRightBar.forEach(pair => { if (imageElement.matches(pair.selector)) { pair.func(imageElement); } }); } else { popupContainer.style.left = rectzL + (rectzW / 2) + offsetRatioX + 'px'; } }, 300); }); TopBar.addEventListener('mouseenter', function() { var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src let rectZ = popup.getBoundingClientRect(); let rectZH = rectZ.height; let rectZW = rectZ.width; let rectZRatio = rectzH / rectzW; let natRatio = natHeight / natWidth; let rectNZRatio = Number(natRatio.toFixed(3)) / Number(rectZRatio.toFixed(3)); // not original Ratio and not scaling mode aplly with arrow indicator if (!((rectNZRatio === 1) || isScale )) { TopBar.style.opacity = '1'; TL.style.background = 'rgba(0, 0, 0, 0.5)'; TR.style.background = 'rgba(0, 0, 0, 0.5)'; TopBar.style.background = 'rgba(0, 0, 0, 0.5)'; style2.innerHTML = `.TopBar::after { display: block; }`; } else { style2.innerHTML = `.TopBar::after { display: none; }`; } }); LeftBar.addEventListener('mouseenter', function() { LeftBar.style.opacity = '1'; let rect = popup.getBoundingClientRect(); rectzRatio = rect.height / rect.width; rectIzRatio = Number(rectIRatio.toFixed(3)) / Number(rectzRatio.toFixed(3)); if ( isLockedX || !( (rectIzRatio === 1) || isScale ) ) { style2.innerHTML = ` .LeftBar::before, .LeftBar::after { display: block; }`; TL.style.background = 'rgba(0, 0, 0, 0.5)'; BL.style.background = 'rgba(0, 0, 0, 0.5)'; LeftBar.style.background = 'rgba(0, 0, 0, 0.5)'; } else { style2.innerHTML = ` .LeftBar::before, .LeftBar::after { display: none; }`; } }); RightBar.addEventListener('mouseenter', function() { RightBar.style.opacity = '1'; let rect = popup.getBoundingClientRect(); rectzRatio = rect.height / rect.width; rectIzRatio = Number(rectIRatio.toFixed(3)) / Number(rectzRatio.toFixed(3)); if ( isLockedX || !( (rectIzRatio === 1) || isScale ) ) { style2.innerHTML = ` .RightBar::before, .RightBar::after { display: block; }`; TR.style.background = 'rgba(0, 0, 0, 0.5)'; BR.style.background = 'rgba(0, 0, 0, 0.5)'; RightBar.style.background = 'rgba(0, 0, 0, 0.5)'; } else { style2.innerHTML = ` .RightBar::before, .RightBar::after { display: none; }`; } }); TopBar.addEventListener('mouseleave', function() { TopBar.style.opacity = '0'; TL.style.background = ''; TR.style.background = ''; }); LeftBar.addEventListener('mouseleave', function() { if (isLockedX) { LeftBar.style.opacity = '1'; } else { LeftBar.style.opacity = '0'; } TL.style.background = ''; BL.style.background = ''; LeftBar.style.background = ''; }); RightBar.addEventListener('mouseleave', function() { if (isLockedX) { RightBar.style.opacity = '1'; } else { RightBar.style.opacity = '0'; } TR.style.background = ''; BR.style.background = ''; RightBar.style.background = ''; }); //------------------------------------------------------------------------- let natXratio, natYratio, natHeight, natWidth; // show popup function showPopup(src, mouseX, mouseY) { if (!isshowPopupEnabled) return; ishidePopupEnabled = true; if (enableP === 0) return; popup.src = src; popup.style.display = 'block'; popupContainer.style.display = 'block'; popupContainer.style.position = 'fixed'; popupContainer.style.transform = 'translate(-50%, -50%) scaleX(1) scaleY(1)'; backdrop.style.display = 'block'; backdrop.style.zIndex = '999'; backdrop.style.backdropFilter = 'blur(10px)'; if (positionP === 'center') { popupContainer.style.top = '50%'; popupContainer.style.left = '50%'; } else { popupContainer.style.top = `${mouseY}px`; popupContainer.style.left = `${mouseX}px`; } let rectI = popup.getBoundingClientRect(); rectIH = rectI.height; rectIW = rectI.width; rectIT = rectI.top; rectIL = rectI.left; var img = new Image(); img.onload = function() { natHeight = img.naturalHeight; natWidth = img.naturalWidth; }; img.src = popup.src natXratio = natWidth / rectIW; natYratio = natHeight / rectIH; rectIRatio = rectIH / rectIW; if (positionP === '') { if (mouseY < window.innerHeight * 0.33) { popupContainer.style.top = mouseY + (rectIH / 2) - 40 + 'px'; } else if (mouseY >= window.innerHeight * 0.33 && mouseY < window.innerHeight * 0.67) { popupContainer.style.top = mouseY + 'px'; } else if (mouseY >= window.innerHeight * 0.67) { popupContainer.style.top = mouseY - (rectIH / 2) + 40 + 'px'; } if (mouseX < window.innerWidth * 0.33) { popupContainer.style.left = mouseX + (rectIW / 2) - 40 + 'px'; } else if (mouseX >= window.innerWidth * 0.33 && mouseX < window.innerWidth * 0.67) { popupContainer.style.left = mouseX + 'px'; } else if (mouseX >= window.innerWidth * 0.67) { popupContainer.style.left = mouseX - (rectIW / 2) + 40 + 'px'; } } if (isAlbum) { LockedXMode(); } } let isAlbum; let currentContainer; document.addEventListener('mouseover', function(e) { if (popupTimer) return; let target = e.target.closest(imgContainers); if (!target) return; if (target.querySelector(nopeElements)) return; currentContainer = target; const imageElement = currentContainer.querySelector(imgElements); specialElements.forEach(pair => { if (imageElement.matches(pair.selector)) { pair.func(imageElement); } }); if (imageElement) { currentZeroImgElement = imageElement; if (currentZeroImgElement) { let pair = albumSelector.find(pair => currentZeroImgElement.matches(pair.imgElement)); if (pair) { let closestAlbumElement = currentZeroImgElement.closest(pair.albumElements); isAlbum = closestAlbumElement && closestAlbumElement.querySelectorAll(pair.imgElement).length > 1; if (isAlbum) { imgElementsList = Array.from(closestAlbumElement.querySelectorAll(pair.imgElement)); let zeroIndex = imgElementsList.indexOf(currentZeroImgElement); TR.textContent = `${zeroIndex + 1}/${imgElementsList.length}`; if (zeroIndex === 0) { LeftBar.style.display = 'none'; } else { LeftBar.style.display = ''; } if (zeroIndex === imgElementsList.length - 1) { RightBar.style.display = 'none'; } else { RightBar.style.display = ''; } } } else { isAlbum = false; TR.textContent = ''; LeftBar.style.display = ''; RightBar.style.display = ''; } } if (intervalP === '') { showPopup(imageElement.src, e.clientX, e.clientY); } else { popupTimer = setTimeout(() => { showPopup(imageElement.src, e.clientX, e.clientY); popupTimer = null; }, parseInt(intervalP)); } } }); //------------------------------------------------------------------------- // hide popup function hidePopup() { if (!ishidePopupEnabled) return; imgElementsList = []; if (popupTimer) { clearTimeout(popupTimer); } popup.style.display = 'none'; popupContainer.style.display = 'none'; NoMode(); popup.style.maxHeight = 'calc(90vh - 10px)'; popup.style.width = ''; popup.style.height = ''; popupContainer.style.left = '50%'; popupContainer.style.top = '50%'; popupContainer.style.position = 'fixed'; popupContainer.style.transform = 'translate(-50%, -50%) scaleX(1) scaleY(1)'; popupContainer.style.transformOrigin = ''; popupContainer.style.outline = ''; backdrop.style.zIndex = ''; backdrop.style.display = 'none'; backdrop.style.backdropFilter = ''; LeftBar.style.opacity = '0'; RightBar.style.opacity = '0'; style2.innerHTML = ` .LeftBar::before, .LeftBar::after, .RighttBar::before, .RighttBar::after { display: none; }`; document.querySelectorAll('.specialElement').forEach(e => e.remove()); clickCount = 0; cropAreaSet = false; CropCover.style.zIndex = '1'; CropCover.style.border = ''; document.querySelectorAll('.cropArea1').forEach(e => e.remove()) document.querySelectorAll('.cropArea2').forEach(e => e.remove()) document.querySelectorAll('.cropArea3').forEach(e => e.remove()) document.querySelectorAll('.cropArea4').forEach(e => e.remove()) var removecropCanvas = document.getElementById('cropCanvas'); removecropCanvas.remove(); CropCover.remove(); } popupContainer.addEventListener('mouseout', function(event) { let relatedTarget = event.relatedTarget; if (relatedTarget && (popupContainer.contains(relatedTarget) || relatedTarget.matches('.imgContainers'))) { return; } document.querySelectorAll('.specialElement').forEach(e => e.remove()); hidePopup(); if (intervalP !== '') { popupTimer = setTimeout(() => { popupTimer = null; }, parseInt(intervalP)); } }); document.addEventListener('keydown', function(event) { if (event.key === "Escape") { event.preventDefault(); hidePopup(); } }); //------------------------------------------------------------------------- // lock popup in screen backdrop.addEventListener('dblclick', function(event) { clearTimeout(clickTimeout); ishidePopupEnabled = true; hidePopup(); }); backdrop.addEventListener('click', function(event) { if (clickTimeout) clearTimeout(clickTimeout); clickTimeout = setTimeout(function() { ResetGeometry(); if (isScale) { isScale = false; isScaleTL = false; isScaleTR = false; isScaleBL = false; isScaleBR = false; ScalingMode0(); } else if (isLockedY) { isLockedY = false; popupContainer.style.border = ''; } else { backdrop.style.zIndex = ''; backdrop.style.display = 'none'; backdrop.style.backdropFilter = ''; isshowPopupEnabled = false; } }, 300); }); } //------------------------------------------------------------------------- // Is to be run ----------------------------------------------------------- if (URLmatched) { 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() { enableP = 1 - enableP; indicatorBar.style.background = enableP ? 'linear-gradient(to right, rgba(50, 190, 152, 0) 0%, rgba(50, 190, 152, 0.5) 25%, rgba(50, 190, 152, 0.5) 75%, rgba(50, 190, 152, 0) 100%)' : 'linear-gradient(to right, rgba(174, 0, 1, 0) 0%, rgba(174, 0, 1, 0.5) 25%, rgba(174, 0, 1, 0.5) 75%, rgba(174, 0, 1, 0) 100%)'; setTimeout(() => { indicatorBar.style.background = '#0000'; }, 1000); if (enableP === 1) { HoverZoomMinus(); } else { document.querySelectorAll('.popup-container').forEach(e => e.remove()); document.querySelectorAll('.popup-backdrop').forEach(e => e.remove()); document.querySelectorAll('.specialElement').forEach(e => e.remove()); } } let hoverTimeout; indicatorBar.addEventListener('mouseenter', () => { hoverTimeout = setTimeout(toggleIndicator, 500); }); indicatorBar.addEventListener('mouseleave', () => { clearTimeout(hoverTimeout); indicatorBar.style.background = '#0000'; }); if (enableP === 1) { HoverZoomMinus(); } } else { return; } })();