图片列表全屏

网页图片全屏查看,缩放, 切换

目前為 2022-05-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name         图片列表全屏
// @namespace    http://tampermonkey.net/
// @version      0.1.1
// @description  网页图片全屏查看,缩放, 切换
// @author       liangxin
// @match        *://*/*
// @grant      GM_registerMenuCommand
// ==/UserScript==

(function() {
    // 图片数组
    let imgs;

    // 图片浏览父容器
    let div;
    // 当前操作的 图片元素;
    let img;
    // 当前操作图片索引
    let imgIndex = 0;
    // 图片大小
    let imgSize;
    // 图片宽高比
    let imgAspectRatio;
    // 图片缩放比例
    let imgZoomNum = 1;
    // 初始缩放比例, 即第一次展示时的缩放比例
    let initImgZoomNum = 1;


    function loading() {
        // 获取图片元素集合
        imgs = Array.from(document.getElementsByTagName("img"));
        // 过滤小图片
        imgs = imgs.filter(img => img.width > 200 && img.height > 200);
        if (imgs.length < 2) {
            return;
        }
        initMenu();
        initEvent();
        // initDiv();
    }
    /**
         * 加载菜单
         */
    let initMenu = () => {
        // 右键菜单
        let msg = `Ctrl + I : 开启图片全屏列表 ESC : 退出图片全屏
            鼠标滚轮: 缩放图片 鼠标拖动: 移动图片
            `;
            const w = unsafeWindow || window;
            GM_registerMenuCommand('图片浏览快捷键表', alert.bind(w, msg));
        }


        /**
         *  加载父级容器
         */
        let initDiv = () => {
            // 每次初始索引
            imgIndex = 0;
            // 如果已有 容器, 则不再重新创建
            if (div) {
                div.style.width = window.innerWidth + "px";
                div.style.height = window.innerHeight + "px";
                div.style.display = "block";
                return;
            }
            div = document.createElement("div");
            div.style.width = window.innerWidth + "px";
            div.style.height = window.innerHeight + "px";
            div.style.backgroundColor = "#000";
            div.style.position = "fixed";
            div.style.top = 0;
            div.style.left = 0;
            div.style.zIndex = 9999999;
            div.style.display = "block";
            div.style.overflow = "hidden";
            document.body.append(div);
        }

        /**
         * 显示图片
         */
        let imgShow = () => {
            let showImg = new Image();
            showImg.src = imgs[imgIndex].src;
            showImg.title = imgs[imgIndex].title === "" ? "第" + (imgIndex + 1) +"/"+imgs.length+ "张" : imgs[imgIndex].title;

            showImg.style.position = "absolute";
            div.innerHTML = showImg.outerHTML;
            img = div.querySelector("img");
            // 判断是否已加载成功
            if (img.complete) {
                imgSize = {
                    "width": img.width,
                    "height": img.height
                };
                imgAspectRatio = getImgAspectRatio(img);
                imgZoomNum = 1;
                setImgSize();
            } else {
                // 如果还未加载成功, 则将 设置大小的操作,写在 图片的 onload 函数中
                img.onload = function() {
                    imgSize = {
                        "width": img.width,
                        "height": img.height
                    };
                    imgAspectRatio = getImgAspectRatio(img);
                    imgZoomNum = 1;
                    setImgSize();
                }
            }
            imgZoomEvent();
            imgMove();

        }


        /**
         * 初始 图片大小
         */
        function setImgSize() {
            let newHeight = window.innerHeight;
            let newWidth = 0;
            do {
                newHeight = newHeight - 5;
                newWidth = calculateWidth(newHeight, imgAspectRatio);
            } while (newWidth > window.innerWidth);
            imgZoom(newHeight / imgSize.height);
            initImgZoomNum = imgZoomNum;
        }

    /**
         * 图片左右居中
         */
    function imgCenter() {
        img.style.marginLeft = (window.innerWidth - img.width) / 2 + "px";
    }

    /**
         * 根据比例关系, 已知 高度, 计算 宽度
         */
    function calculateWidth(heigth, aspectRatio) {
        return parseInt(heigth * aspectRatio.width / aspectRatio.height);
    }

    /**
         * 根据比例关系, 已知 宽度, 计算 高度
         */
    function calculateHeight(width, aspectRatio) {
        return parseInt(width * aspectRatio.height / aspectRatio.width);
    }

    /**
         * 缩放图片
         */
    let imgZoom = (zoom = 1) => {
        let newHeight = float_calculator.mul(imgSize.height, zoom);
        img.height = parseInt(newHeight);
        img.width = calculateWidth(newHeight, imgAspectRatio);
        imgCenter();
        showMsg.show(parseInt(float_calculator.mul(zoom, 100)) + "%");
        imgZoomNum = zoom;
        return false;
    }

    /**
         * 鼠标滚轮缩放事件
         */
    let imgZoomEvent = () => {
        // 缩放基数
        let zoom = 0.1;
        let zoomEvent = (zoomOpt) => {
            if (initImgZoomNum == imgZoomNum) {
                let i = (imgZoomNum * 100) % (zoom * 100);
                if (i > 0) {
                    imgZoomNum = (imgZoomNum * 100 + zoom * 100 - i) / 100
                }
            }
            if (zoomOpt) {
                // 向上 放大
                imgZoomNum = float_calculator.add(imgZoomNum, zoom)
            } else {
                // 向下 // 缩小
                imgZoomNum = float_calculator.add(imgZoomNum, -zoom)
            }
            if (imgZoomNum < zoom) {
                return;
            }
            imgZoom(imgZoomNum);
            return false;
        }
        div.onmousewheel = function(e) {
            zoomEvent(e.wheelDelta > 0);
        };


        // 双击回复为 初始缩放比例
        div.addEventListener("dblclick", e => {
            imgZoom(initImgZoomNum);
        })
    }

    let imgMove = () => {

        let imgTop = 0;
        let imgLeft = 0;
        let mx = 0;
        let my = 0;

        img.ondragstart = e => {
            mx = e.screenX;
            my = e.screenY;
            if (img.style.top === "") {
                imgTop = 0;
                imgLeft = 0;
            }
        }

        img.ondrag = e => {
            if (e.screenY == 0 && e.screenX == 0) {
                return
            }
            imgTop = imgTop + e.screenY - my;
            imgLeft = imgLeft + e.screenX - mx;
            mx = e.screenX;
            my = e.screenY;
            img.style.top = imgTop + "px";
            img.style.left = imgLeft + "px";

        }

    }

    /**
         * 初始化事件
         */
    let initEvent = () => {
        window.addEventListener("keydown", e => {
            // <-  和 -> 切换图片
            if (e.keyCode == 37 || e.keyCode == 39) {
                if (e.keyCode == 39) {
                    imgIndex++;
                    imgIndex = imgIndex >= imgs.length ? 0 : imgIndex;
                } else {
                    imgIndex--;
                    imgIndex = imgIndex < 0 ? imgs.length - 1 : imgIndex;
                }
                imgShow();
            }
            // ESC 键 隐藏
            if (e.keyCode == 27) {
                div.style.display = "none";
            }
            // Ctrl + I  开启浏览
            if (e.ctrlKey && e.keyCode == 73) {
                initDiv();
                imgShow();
            }
        })

    }

    window.addEventListener("load",e=>{
        loading();
    });





    //---------------------------- 工具方法 ------------------

    /**
         * 消息对象
         */
    window.showMsg = {
        flag: false,
        msgSpan: null,
        msgTimeOut: null,
        show: function(m, s = 2) {
            // 如果 已有消息, 则清除, 并清除之前的延迟计时器
            if (this.msgSpan) {
                this.msgSpan.remove();
                clearTimeout(this.msgTimeOut);
            }
            this.msgSpan = document.createElement("span");
            document.body.append(this.msgSpan);
            this.msgSpan.innerHTML = m;
            this.msgSpan.style.position = "fixed";
            this.msgSpan.style.top = "50px"
            this.msgSpan.style.left = "49vw";
            this.msgSpan.style.backgroundColor = "#000";
            this.msgSpan.style.color = "#fff";
            this.msgSpan.style.lineHeight = "30px";
            this.msgSpan.style.padding = "0 10px";
            this.msgSpan.style.opacity = 0.5;
            this.msgSpan.style.zIndex = 2147483647;
            this.msgSpan.style.display = "block";
            this.msgSpan.style.borderRadius = "10px";
            this.msgSpan.style.minWidth = "105px";
            this.msgSpan.style.textAlign = "center";

            // 延迟删除
            this.msgTimeOut = setTimeout(() => {
                this.msgSpan.remove();
                this.flag = false;
            }, s * 1000);
        }
    }

    /**
         * 获取图片比例 [宽,高]
         */
    function getImgAspectRatio(img) {
        let i = img.width / img.height;
        console.log("比例: " + img.width + " / " + img.height + " = " + i);
        return i > 1 ? {
            "width": i,
            "height": 1
        } : {
            "width": 1,
            "height": 1 / i
        };
    }


    // 自定义高精度浮点数运算
    // 对象格式写法
    var float_calculator = {
        /**
             * 1.记录两个运算数小数点后的位数
             * 2.将其转化为整数类型进行运算
             * 3.移动小数点的位置
             **/
        add: function(arg1, arg2) {
            var r1, r2, m;
            try {
                //取小数位长度
                r1 = arg1.toString().split(".")[1].length;
                r2 = arg2.toString().split(".")[1].length;
            } catch (e) {
                r1 = 0;
                r2 = 0;
            }
            m = Math.pow(10, Math.max(r1, r2)); //计算因子

            return (arg1 * m + arg2 * m) / m;
        },
        minus: function(arg1, arg2) {
            return this.add(arg1, -arg2);
        },
        mul: function(arg1, arg2) {
            var r1, r2, m;
            try {
                //取小数位长度
                r1 = arg1.toString().split(".")[1].length;
                r2 = arg2.toString().split(".")[1].length;
            } catch (e) {
                r1 = 0;
                r2 = 0;
            }
            m = Math.pow(10, Math.max(r1, r2)); //计算因子

            return (arg1 * m) * (arg2 * m) / (m * m);
        }
    };
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址