js实现仿pc端微信查看图片功能

       使用js实现类似微信图片查看器的功能,可以切换图片,实现图片的放大、缩小、旋转、平移和下载功能。直接上页面效果图。因为项目需求,使用react框架+electron封装成了桌面应用,作为单独的弹窗功能,在页面右上角添加窗口操作按钮。

1. 放大/缩小功能,可通过滚轮或点击底部按钮来实现

    _large(num) {
        let { scaling } = this.state;
        scaling = Math.trunc(scaling) >= 10 ? 10 : scaling + num; // 缩放最大10倍
        this.setState({
            scaling
        });
        this._mouseEnterImg(scaling);
    }
    _small(num) {
        let { scaling, moveX, moveY } = this.state;
        scaling = scaling - num <= 0.1 ? 0.1 : scaling - num; // 缩放最小0.1倍
        if (this.pointType === 'move') {
            let n = Math.round((scaling - 1) / num);
            if (moveX !== 0) {
                moveX -= moveX / n;
            }
            if (moveY !== 0) {
                moveY -= moveY / n;
            }
        } else {
            moveX = 0;
            moveY = 0;
        }
        this.setState({
            scaling,
            moveX,
            moveY
        });
        this._mouseEnterImg(scaling);
    }

2. 放大图片长宽超出最大值时,可以点击鼠标实现拖拽图片显示

    _mouseDown = e => {
        e.preventDefault();
        const { scaling } = this.state;
        if (this.pointType === 'default') return;
        // 获取img-box img的宽度和高度
        const boxW = document.body.clientWidth;
        const boxH = document.body.clientHeight - 26 - 60;
        const imgW = this.refImg.width * scaling;
        const imgH = this.refImg.height * scaling;
        let startX = e.clientX; // 鼠标按下的位置
        let startY = e.clientY;
        this.refImg.onmousemove = e => {
            e.preventDefault();
            let { moveX, moveY } = this.state;
            const currentX = e.clientX;
            const currentY = e.clientY;
            let disX = currentX - startX; // 鼠标移动的像素 往右 往上是正数
            let disY = currentY - startY;
            if (imgW > boxW) {
                if (disX > 0 && (imgW - boxW) / 2 - moveX * scaling > 0) {
                    // 往右走
                    moveX += disX / scaling;
                    if ((imgW - boxW) / 2 - moveX * scaling < 0) {
                        moveX = (imgW - boxW) / 2 / scaling;
                    }
                } else if (disX < 0 && (imgW - boxW) / 2 + moveX * scaling > 0) {
                    // 往左走
                    moveX += disX / scaling;
                    if ((imgW - boxW) / 2 + moveX * scaling < 0) {
                        moveX = ((imgW - boxW) / 2 / scaling) * -1;
                    }
                }
            }
            if (imgH > boxH) {
                if (disY > 0 && (imgH - boxH) / 2 - moveY * scaling > 0) {
                    // 往下走
                    moveY += disY / scaling;
                    if ((imgH - boxH) / 2 - moveY * scaling < 0) {
                        moveY = (imgH - boxH) / 2 / scaling;
                    }
                } else if (disY < 0 && (imgH - boxH) / 2 + moveY * scaling > 0) {
                    // 往上走
                    moveY += disY / scaling;
                    if ((imgH - boxH) / 2 + moveY * scaling < 0) {
                        moveY = ((imgH - boxH) / 2 / scaling) * -1;
                    }
                }
            }
            startX = currentX;
            startY = currentY;
            this.setState({
                moveX,
                moveY
            });
        };
        // 鼠标弹起停止移动
        this.refImg.onmouseleave = () => {
            this.refImg.onmousemove = null;
            this.refImg.onmouseup = null;
        };
        this.refImg.onmouseup = () => {
            this.refImg.onmousemove = null;
            this.refImg.onmouseup = null;
        };
    };

3. 图片下载功能通过a标签download属性来实现

    _download = () => {
        let aD = document.createElement('a');
        aD.href = this.refImg.src;
        aD.download = `图片_${new Date().getTime() * Math.floor(Math.random() * 10000)}`;
        aD.click();
    };

4. 最后主要的render函数,其中Header组件为窗口操作按钮,添加css样式 -webkit-app-region: drag;让窗口可以拖动,如果不用electron封装,可以不用设置这个样式;Footer为底部操作按钮组件。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值