图片放大油猴脚本(悬浮按钮,拖动,旋转)

点击图片放大到屏幕显示的最大尺寸,并支持滚轮放大、拖动和旋转,点击关闭放大显示的图片,禁用图片原有的点击功能。

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

// ==UserScript==
// @name         图片放大油猴脚本(悬浮按钮,拖动,旋转)
// @namespace    http://your.namespace.com
// @version      1.9
// @description  点击图片放大到屏幕显示的最大尺寸,并支持滚轮放大、拖动和旋转,点击关闭放大显示的图片,禁用图片原有的点击功能。
// @author       肆散的尘埃i
// @match        https://happy.5ge.net/*
// @match        http*://*/*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // 自动执行URL列表
    var urlList = [
        'https://happy.5ge.net'
    ];

    // 添加样式
    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 {
                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: 80px;
            }
            .gm-rotate-right {
                bottom: 20px;
                right: 20px;
            }
            .gm-close-button {
                top: 20px;
                right: 20px;
            }
        `);
    }

    // 添加悬浮图片按钮
    function addFloatingButton() {
        var $floatingButton = document.createElement('div');
        $floatingButton.classList.add('gm-floating-button');
        $floatingButton.textContent = '🔍';
        document.body.appendChild($floatingButton);

        // 点击悬浮按钮执行 disableImageClick 操作
        $floatingButton.addEventListener('click', function() {
            console.log("悬浮图片被点击~");
            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 scale = 1;
    var rotation = 0;
    var translateX = 0;
    var translateY = 0;
    var lastX = 0;
    var lastY = 0;

    // 屏蔽图片默认点击功能
    function disableImageClick() {
        var images = 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();
                    enlargeImage(e.target); // 放大图片
                });
            }
        }
    }

    // 添加放大功能
    function enlargeImage(imgElement) {
        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, imgElement);
            }
        });

        // 按Esc键关闭放大图片
        document.addEventListener('keydown', function onEscPress(e) {
            if (e.key === 'Escape') {
                closeEnlargedImage($expandedContainer, imgElement);
                document.removeEventListener('keydown', onEscPress);
            }
        });

        // 鼠标拖动
        $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 = Math.max(-1, Math.min(1, e.deltaY));
            scale = Math.max(0.1, scale + delta * 0.2);

            $expandedImage.style.transform = `scale(${scale}) rotate(${rotation}deg) translate(${translateX}px, ${translateY}px)`;

            // 输出当前放大倍数
            //console.log(`当前放大倍数:${scale}`);
        });

        // 初始化位置和样式
        $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'), document.querySelector('img[data-gm-enlargeable][style*="pointer-events: none;"]'));
            });
        }
        $rotateLeftButton.style.display = 'flex';
        $rotateRightButton.style.display = 'flex';
        $closeButton.style.display = 'flex';
    }

    // 隐藏控制按钮
    function hideControlButtons() {
        if ($rotateLeftButton) {
            $rotateLeftButton.style.display = 'none';
        }
        if ($rotateRightButton) {
            $rotateRightButton.style.display = 'none';
        }
        if ($closeButton) {
            $closeButton.style.display = 'none';
        }
    }

    // 关闭放大图片
    function closeEnlargedImage($expandedContainer, imgElement) {
        document.body.style.overflow = 'auto';// 取消大图查看时允许滑动
        $expandedContainer.style.display = 'none';
        $expandedContainer.remove();
        imgElement.style.pointerEvents = ''; // 恢复原始图片的点击功能
        hideControlButtons();
        resetTransformations();
    }

    // 重置转换属性
    function resetTransformations() {
        scale = 1;
        rotation = 0;
        translateX = 0;
        translateY = 0;
    }

    // 检查当前网址是否在urlList中
    function checkCurrentUrl() {
        var currentUrl = window.location.origin;
        if (urlList.includes(currentUrl)) {
            // 如果匹配,执行操作
            disableImageClick();
        }
    }

    // 初始化函数
    function init() {
        addStyles();
        checkCurrentUrl();
        addFloatingButton();
    }

    // 执行初始化函数
    init();
})();