Hover Zoom Minus --

image popup: zoom, pan, scroll, pin, scale

目前為 2024-03-18 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name             Hover Zoom Minus --
// @namespace        Hover Zoom Minus --
// @version          1.0.6
// @description      image popup: zoom, pan, scroll, pin, scale
// @author           Ein, 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 make it move along with the mouse, click again to release (indicated by green border)
// 4. while being locked"Y" the wheel up/down will act as scroll up/down
// 5. double click will lock it on screen preventing it from being hidden
// 6. 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
// 7. 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
// 8. double clicking on blurred background will de-spawn popup
// 9. click  on top right corner to scale image
// 10. 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', '0'],
        '9gag.com': [1, 'center', '0'],
        'feedly.com': [1, 'center', '200'],
        '4chan.org': [1, '', '400'],
        'deviantart.com': [0, 'center', '300']
    };

    // image container [hover box where popup triggers]
    const imgContainers = `
    /* ------- reddit */ ._3BxRNDoASi9FbGX01ewiLg, ._3Oa0THmZ3f5iZXAQ0hBJ0k > div, ._35oEP5zLnhKEbj5BlkTBUA, ._1ti9kvv_PMZEF2phzAjsGW > div, ._28TEYBuEdOuE3kN6UyoKMa div, ._3Oa0THmZ3f5iZXAQ0hBJ0k.WjuR4W-BBrvdtABBeKUMx div, ._3m20hIKOhTTeMgPnfMbVNN,
    /* --------- 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,
    /* --------- 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 those that are already on the DOM tree
    // example reddit will not include all until you press tha navigator. so most of the time this will only load a few ones
    // unless you update it via interacting with reddit's navigator button or maybe you could make a special function for "specialElements" so it will load and include all image in the DOM tree
    let albumSelector = [
    /* ------- reddit */ { imgElement: '._1dwExqTGJH2jnA-MYGkEL-', albumElements: '._1apobczT0TzIKMWpza0OhL' },
    /* ------- sample */ { imgElement: 'imgElementSelector2', albumElements: 'albumSelector2' },
    ];

    // specialElements were if targeted, will call it's paired function
    // for convenience an element class "specialElement" will be remove on mouseout and hidepopup() 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 }
    ];
    // 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;
        if (parentElement.tagName === 'A') {
            const href = parentElement.getAttribute('href');
            if (href.endsWith('.webm')) {
                const videoElement = document.createElement('video');
                videoElement.src = href;
                videoElement.controls = true;
                parentElement.replaceChild(videoElement, imageElement);
            } else if (href.endsWith('.gif')) {
                imageElement.setAttribute('src', href);
            }
        } else {
            let src = imageElement.getAttribute('src');
            if (src && src.includes('s.jpg')) {
                let newSrc = src.replace('s.jpg', '.jpg');
                imageElement.setAttribute('src', newSrc);
            }
        }
    }
    // reddit: added the label/description of image along with the popup
    function SP2(imageElement) {
        console.log('special function is called.');
        let closestElement = imageElement.closest('.m3aNC6yp8RrNM_-a0rrfa, .kcerW9lbT-se3SXd-wp2i');
        if (!closestElement) {
            console.log('No matching ancestor element found.');
            return; // Exit the function if closestElement is null
        }
        let descendantElement = closestElement.querySelector('._15nNdGlBIgryHV04IfAfpA');
        if (descendantElement) {
            let title = descendantElement.getAttribute('title');
            console.log('title:', 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;
        }
    }

    //-------------------------------------------------------------------------

    // 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;
			z-index: 1001;
			cursor: move;
		}
		.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;
		}
		.LockedX {
			height: 40px;
			width: calc(100% - 80px);
			background: #0000;
			position: absolute;
            left: 40px;
			bottom: 0;
			z-index: 9999;
		}
        .scaleBox,
        .scaleCorner {
            height: 40px;
            width: 40px;
            background: #0000;
			position: absolute;
        }
        .scaleBox {
            z-index: 9999;
        }
        .scaleCorner {
			z-index: 9998;
        }
        .scaleBox.TR,
        .scaleCorner.TR2 {
			top: 0;
            right: 0;
         }
        .scaleBox.TL,
        .scaleCorner.TL2 {
			top: 0;
            left: 0;
         }
        .scaleBox.BR,
        .scaleCorner.BR2 {
			bottom: 0;
            right: 0;
         }
        .scaleBox.BL,
        .scaleCorner.BL2 {
			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 LockedX = document.createElement('div');
        LockedX.className = 'LockedX';
        popupContainer.appendChild(LockedX);

        const TR = document.createElement('div');
        TR.className = 'scaleBox TR';
        popupContainer.appendChild(TR);
        const TL = document.createElement('div');
        TL.className = 'scaleBox TL';
        popupContainer.appendChild(TL);
        const BR = document.createElement('div');
        BR.className = 'scaleBox BR';
        popupContainer.appendChild(BR);
        const BL = document.createElement('div');
        BL.className = 'scaleBox BL';
        popupContainer.appendChild(BL);

        const TR2 = document.createElement('div');
        TR2.className = 'scaleCorner TR2';
        popupContainer.appendChild(TR2);
        const TL2 = document.createElement('div');
        TL2.className = 'scaleCorner TL2';
        popupContainer.appendChild(TL2);
        const BR2 = document.createElement('div');
        BR2.className = 'scaleCorner BR2';
        popupContainer.appendChild(BR2);
        const BL2 = document.createElement('div');
        BL2.className = 'scaleCorner BL2';
        popupContainer.appendChild(BL2);

        //-------------------------------------------------------------------------

        // Zoom, Pan, Scroll

        let isLockedY = false;
        let isLockedX = false;
        let offsetX, offsetY, offsetXR, offsetYT, offsetXL, offsetYB, rectT, rectH, rectL, rectW, scaleCurrentX, scaleCurrentY;
        let scale = 1;
        const ZOOM_SPEED = 0.005;
        let clickTimeout;
        let popupTimer;

        let isScale, isScaleTR, isScaleBR, isScaleTL, isScaleBL;
        popupContainer.addEventListener('click', function(event) {
            if (clickTimeout) clearTimeout(clickTimeout);
            clickTimeout = setTimeout(function() {
                if (event.target.matches('.LockedX') || event.target.closest('.LockedX') || event.target.matches('.scaleBox') || event.target.closest('.scaleBox')) {
                    event.stopPropagation();
                } else {
                    isLockedY = !isLockedY;
                    isScale = false;
                    TR2.style.border = '';
                    BR2.style.border = '';
                    TL2.style.border = '';
                    BL2.style.border = '';
                    if (isLockedY) {
                        popupContainer.style.outline = ishidePopupEnabled ? '' : '6px solid #ae0001';
                        isLockedX = false;
                        popupContainer.style.borderTop = '';
                        popupContainer.style.borderBottom = '';
                        popupContainer.style.borderLeft = '6px solid #00ff00';
                        popupContainer.style.borderRight = '6px solid #00ff00';
                        let rect = popupContainer.getBoundingClientRect();
                        offsetX = event.clientX - rect.left - (rect.width / 2);
                        offsetY = event.clientY - rect.top - (rect.height / 2);
                    } else {
                        popupContainer.style.border = '';
                    }
                }}, 300);
        });

        document.querySelectorAll('.scaleBox').forEach(element => {
            element.addEventListener('click', function(event) {
                ishidePopupEnabled = false;
                isScale = !isScale;
                if (isScale) {
                    isLockedY = false;
                    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 = element.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;
                    rectH = rect.height;
                    rectW = rect.width;
                    rectL = rect.left;
                } else {
                    TR2.style.border = '';
                    BR2.style.border = '';
                    TL2.style.border = '';
                    BL2.style.border = '';
                    popupContainer.style.outline = '6px solid #ae0001';
                }
            });
        });

        TR.addEventListener('click', function(event) {
            isScaleTR = !isScaleTR;
        });
        TL.addEventListener('click', function(event) {
            isScaleTL = !isScaleTL;
        });
        BL.addEventListener('click', function(event) {
            isScaleBL = !isScaleBL;
        });
        BR.addEventListener('click', function(event) {
            isScaleBR = !isScaleBR;
        });

        let scaleFactorY, scaleFactorX;
        document.querySelectorAll('.scaleBox').forEach(element => {
            element.addEventListener('mouseenter', function(event) {
                element.style.height = '100%';
                element.style.width = '100%';
                TL2.style.borderTop = '6px solid #0000ff';
                TR2.style.borderTop = '6px solid #0000ff';
                TL2.style.borderLeft = '6px solid #0000ff';
                BL2.style.borderLeft = '6px solid #0000ff';
                TR2.style.borderRight = '6px solid #0000ff';
                BR2.style.borderRight = '6px solid #0000ff';
                BR2.style.borderBottom = '6px solid #0000ff';
                BL2.style.borderBottom = '6px solid #0000ff';
            });
        });
        document.querySelectorAll('.scaleBox').forEach(element => {
            element.addEventListener('mouseleave', function(event) {
                element.style.height = '40px';
                element.style.width = '40px';
                if (!isScale) {
                    TL2.style.border = '';
                    TR2.style.border = '';
                    BL2.style.border = '';
                    BR2.style.border = '';
                }
            });
        });


        document.addEventListener('mousemove', function(event) {
            if (isLockedY) {
                popupContainer.style.left = (event.clientX - offsetX) + 'px';
                popupContainer.style.top = (event.clientY - offsetY) + 'px';
            } else if (isScale) {
                TL2.style.borderTop = '6px solid #0000ff';
                TR2.style.borderTop = '6px solid #0000ff';
                TL2.style.borderLeft = '6px solid #0000ff';
                BL2.style.borderLeft = '6px solid #0000ff';
                TR2.style.borderRight = '6px solid #0000ff';
                BR2.style.borderRight = '6px solid #0000ff';
                BR2.style.borderBottom = '6px solid #0000ff';
                BL2.style.borderBottom = '6px solid #0000ff';
                if (isScaleTR) {
                    scaleFactorY = scaleCurrentY * (1 + (2 * (rectT - event.clientY + offsetYT) / (rectH)));
                    scaleFactorX = scaleCurrentX * (-1 + (2 * (-rectL + event.clientX + offsetXR) / (rectW)));
                } else if (isScaleBR) {
                    scaleFactorY = scaleCurrentY * (-1 + (2 * (-rectT + event.clientY + offsetYB) / (rectH)));
                    scaleFactorX = scaleCurrentX * (-1 + (2 * (-rectL + event.clientX + offsetXR) / (rectW)));
                } else if (isScaleTL) {
                    scaleFactorY = scaleCurrentY * (1 + (2 * (rectT - event.clientY + offsetYT) / (rectH)));
                    scaleFactorX = scaleCurrentX * (1 + (2 * (rectL - event.clientX + offsetXL) / (rectW)));
                } else {
                    scaleFactorY = scaleCurrentY * (-1 + (2 * (-rectT + event.clientY + offsetYB) / (rectH)));
                    scaleFactorX = scaleCurrentX * (1 + (2 * (rectL - event.clientX + offsetXL) / (rectW)));
                }
                popupContainer.style.transform = `translate(-50%, -50%) scale(${scaleFactorX}, ${scaleFactorY})`
            }
        });

        let imgElementsList = [];
        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) {
                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 = event.deltaY > 0 ? 1 : -1;
                        let newIndex = (zeroIndex + direction + imgElementsList.length) % imgElementsList.length;
                        currentZeroImgElement = imgElementsList[newIndex];
                        popup.src = currentZeroImgElement.src;
                    }
                }
            } 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);

        //-------------------------------------------------------------------------

        // show popup
        function showPopup(src, mouseX, mouseY) {
            if (!isshowPopupEnabled) 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 currentZeroImgElement;

        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);

            specialElements.forEach(pair => {
                if (imageElement.matches(pair.selector)) {
                    pair.func(imageElement);
                }
            });

            if (imageElement) {
                currentZeroImgElement = imageElement;
                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 = [];
            isshowPopupEnabled = true;
            if (popupTimer) {
                clearTimeout(popupTimer);
            }
            document.body.appendChild(backdrop);
            popup.style.display = 'none';
            popupContainer.style.display = 'none';
            popupContainer.style.left = '50%';
            popupContainer.style.top = '50%';
            popupContainer.style.position = 'fixed';
            popupContainer.style.transform = 'translate(-50%, -50%) scaleX(1) scaleY(1)';
            popupContainer.style.border = '';
            popupContainer.style.outline = '';
            backdrop.style.zIndex = '';
            backdrop.style.display = 'none';
            backdrop.style.backdropFilter = '';
            isLockedY = false;
            isLockedX = false;
            document.querySelectorAll('.specialElement').forEach(e => e.remove());
        }

        popupContainer.addEventListener('mouseout', function(event) {
            document.querySelectorAll('.specialElement').forEach(e => e.remove());

            let relatedTarget = event.relatedTarget;
            if (relatedTarget && (popupContainer.contains(relatedTarget) || relatedTarget.matches('.imgContainers') || relatedTarget.closest('.imgContainers'))) {
                return;
            }

            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
        let ishidePopupEnabled = true;

        function togglehidePopup(event) {
            ishidePopupEnabled = !ishidePopupEnabled;
            popupContainer.style.outline = ishidePopupEnabled ? '' : '6px solid #ae0001';
        }

        popupContainer.addEventListener('dblclick', function(event) {
            clearTimeout(clickTimeout);
            togglehidePopup();
        });
        backdrop.addEventListener('dblclick', function(event) {
            clearTimeout(clickTimeout);
            ishidePopupEnabled = true;
            hidePopup();
        });


        backdrop.addEventListener('click', function(event) {
            if (clickTimeout) clearTimeout(clickTimeout);
            clickTimeout = setTimeout(function() {
                if (isScale) {
                    isScale = false;
                } else {
                    backdrop.style.zIndex = '';
                    backdrop.style.display = 'none';
                    backdrop.style.backdropFilter = '';
                    isshowPopupEnabled = false;
                }
            }, 300);
        });


        // Album scrolling
        LockedX.addEventListener('mouseenter', function() {
            LockedX.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%)';
        });

        LockedX.addEventListener('mouseleave', function() {
            LockedX.style.background = '#0000';
        });

        LockedX.addEventListener('click', function(event) {
            ishidePopupEnabled = false;
            isLockedX = !isLockedX;
            if (isLockedX) {
                isLockedY = false;
                popupContainer.style.borderTop = '6px solid #00ff00';
                popupContainer.style.borderBottom = '6px solid #00ff00';
                popupContainer.style.borderLeft = '';
                popupContainer.style.borderRight = '';
                popupContainer.style.outline = '';
            } else {
                popupContainer.style.border = '';
                popupContainer.style.outline = '6px solid #ae0001';
            }

        });
    }

    //-------------------------------------------------------------------------

    // 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 {
                const existingPopup = document.body.querySelector('.popup-container');
                if (existingPopup) document.body.removeChild(existingPopup);
                const existingBackdrop = document.body.querySelector('.popup-backdrop');
                if (existingBackdrop) document.body.removeChild(existingBackdrop);
            }
        }
        let hoverTimeout;
        indicatorBar.addEventListener('mouseenter', () => {
            hoverTimeout = setTimeout(toggleIndicator, 500);
        });
        indicatorBar.addEventListener('mouseleave', () => {
            clearTimeout(hoverTimeout);
            indicatorBar.style.background = '#0000';
        });
        if (enableP === 1) {
            HoverZoomMinus();
        }
    } else {
        return;
    }

})();