vue项目实现图片缩放与拖拽功能

这篇具有很好参考价值的文章主要介绍了vue项目实现图片缩放与拖拽功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在项目开发中遇到一个需求:

1:用鼠标滚轮可对图片进行缩放处理

2:点击按钮可对图片进行缩放处理

3:可对图片进行拖拽处理

我在开发中通过自己实现与百度查看优秀的铁子进行了两种类型的使用

1:个人进行实现:

源码:

<template>
    <div class="pictureDetails">
        <div class="pictureDetails-box">

            <!-- 图片区 -->
            <div class="box-img">

                <div style="width: 100%" class="left" @mousewheel.prevent="rollImg">
                    <img :src="imgSrc" class="img" ref="imgDiv" :style="{ transform: 'scale(' + zoomD + ')' }"
                        @mousedown="move" />
                </div>

                <!-- 按钮 -->
                <div class="Button-area">
                    <ol>
                        <li @click="zoomMax">
                            大
                        </li>
                        <li @click="zoomMin">
                            小
                        </li>
                        <li v-if="love" @click="btnLoveFlage">
                            未赞
                        </li>
                        <li v-else @click="btnLoveFlage">
                            已赞
                            <!-- <img src="@/assets/images/pictureDetails/Collection.png" alt="点赞icon"> -->
                        </li>
                        <li @click="downloadImg(imgSrc, '哇哈哈')
                        ">
                            下载
                        </li>
                    </ol>
                </div>
            </div>
        </div>

    </div>
</template>

<script>

export default {

    data() {
        return {
            zoomD: 1,
            love: false,
            imgSrc: 'https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675',  //横图
            // imgSrc: 'https://img1.baidu.com/it/u=1518057857,2376515959&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1675530000&t=d847d2430e87d04936f7d07f38cf60c5',  //竖图


        }
    },
    created() {
        //根据接口判断当前详情是否已经收藏
        this.love = true;
    },
    mounted() {

    },
    methods: {
        //移动demo
        move(e) {
            e.preventDefault();
            // 获取元素
            var personBox = document.querySelector(".left");
            var img = document.querySelector(".img");
            var x = e.pageX - img.offsetLeft;
            var y = e.pageY - img.offsetTop;

            // 添加鼠标移动事件
            personBox.addEventListener("mousemove", move);
            function move(e) {
                img.style.left = e.pageX - x + "px";
                img.style.top = e.pageY - y + "px";
            }
            // 添加鼠标抬起事件,鼠标抬起,将事件移除
            img.addEventListener("mouseup", function () {
                personBox.removeEventListener("mousemove", move);
            });
            // 鼠标离开父级元素,把事件移除
            personBox.addEventListener("mouseout", function () {
                personBox.removeEventListener("mousemove", move);
            });
        },
        // 缩放图片
        rollImg(e) {
            let direction = e.deltaY > 0 ? 'down' : 'up'
            if (direction === 'up') {
                // 滑轮向上滚动
                this.large();
            } else {
                // 滑轮向下滚动
                this.Small();
            }
        },
        //缩小按钮方法
        zoomMin() {
            this.Small();
        },
        //放大按钮方法
        zoomMax() {
            this.large();
        },

        //大
        large() {
            this.$nextTick(() => {
                if (this.zoomD < 6) {
                    this.zoomD += 0.10
                }
                document.querySelector('.img').style.transform = `matrix(${this.zoomD}, 0, 0,${this.zoomD}, 0, 0)`
            })
        },
        // 小
        Small() {
            this.$nextTick(() => {
                if (this.zoomD > 0.3) {
                    this.zoomD -= 0.10
                }
                document.querySelector('.img').style.transform = `matrix(${this.zoomD}, 0, 0, ${this.zoomD}, 0, 0)`
            })
        },
        //点击下载图片
        downloadImg(url, name) {
            let image = new Image();
            image.setAttribute("crossOrigin", "anonymous");
            image.src = url;
            image.onload = () => {
                let canvas = document.createElement("canvas");
                canvas.width = image.width;
                canvas.height = image.height;
                let ctx = canvas.getContext("2d");
                ctx.drawImage(image, 0, 0, image.width, image.height);
                canvas.toBlob((blob) => {
                    let url = URL.createObjectURL(blob);
                    this.download(url, name);
                    // 用完释放URL对象
                    URL.revokeObjectURL(url);
                });
            };
        },
        download(href, name) {
            let eleLink = document.createElement("a");
            eleLink.download = name;
            eleLink.href = href;
            eleLink.click();
            eleLink.remove();
        },

        //点赞收藏
        btnLoveFlage() {
            this.love = this.love == true ? false : true;
            console.log(this.love);
        }
    }
}
</script>

<style lang="scss" scoped>
.pictureDetails {
    width: 100%;
    height: auto;
    background-color: #F3F1EE;
    display: flex;
    align-items: center;
    flex-direction: column;
    justify-content: center;

    .pictureDetails-box {
        width: 1200px;
        // height: 800px;
        display: flex;
        flex-direction: column;

        .box-img {
            width: 1200px;
            height: 662px;
            margin-bottom: 20px;
            background: #DFDAD3;
            position: relative;

            .left {
                position: absolute;
                width: 660px;
                height: 100%;
                float: left;
                overflow: hidden;

                display: flex;
                align-items: center;
                justify-content: center;
            }

            .img {
                position: absolute;
                /* top: 5px; */
                /* left: 7px; */
                // max-width: 923px;
                // max-height: 460px;
                cursor: move;
            }

            .Button-area {
                width: 42px;
                height: 200px;
                // background-color: pink;
                position: absolute;
                right: -50px;
                top: 0px;

                ol {
                    width: 100%;
                    height: 100%;
                    display: flex;
                    flex-direction: column;
                    justify-content: space-between;

                    li {
                        width: 43px;
                        height: 42px;
                        background: #A58773;
                        cursor: pointer;
                        // padding: 8px 8px;
                        box-sizing: border-box;
                        border-radius: 6px;

                      display: flex;
                      align-items: center;
                      justify-content: center;
                    }

                    li:hover {
                        background: #634d3f;
                    }
                }
            }
        }
    }
}
</style>

效果:

vue图片放大缩小拖动,vue.js,javascript,前端,Powered by 金山文档

2:通过借鉴他人优秀帖子所修改实现

源码:

<template>
    <!-- 舆图库详情页 -->
    <div class="mainPage">

        <div class="watchMap">
            <div class="imgBox" ref="maskBox" @mousedown="onmousedownHandle">
                <img :src="imageUrl" alt="" :style="{
                    width: imgW + 'px',
                    height: imgH + 'px',
                    top: top + 'px',
                    left: left + 'px',
                    transform: scale,
                }" />
            </div>

            <div class="Tools">
                <div class="Tools-item" @click="imgScaleHandle(0.25)">
                    大
                </div>
                <div class="Tools-item" @click="imgScaleHandle(-0.25)">
                    小
                </div>
                <div class="Tools-item">
                    藏
                </div>
                <div class="Tools-item" @click="
    downloadByBlob(
        'https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675',
        'name'
    )
                ">
                    下载
                </div>
            </div>
        </div>

    </div>
</template>

<script>
export default {

    data() {
        return {
            imageUrl:
                "https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675",

            imgW: 0,
            imgH: 0,
            deg: 0,
            top: 0,
            left: 0,
            scale: "scale(1)",
            size: 0,
            mousewheelevt: null,
        };
    },

    mounted() {
        //初始化图片
        this.initImage();

        // 兼容火狐浏览器
        this.mousewheelevt = /Firefox/i.test(navigator.userAgent)
            ? "DOMMouseScroll"
            : "mousewheel";
        // 为空间区域绑定鼠标滚轮事件 =》 处理函数是wheelHandle
        // 如果你监听了window的scroll或者touchmove事件,你应该把passive设置为true,这样滚动就会流畅很多
        this.$refs.maskBox.addEventListener(this.mousewheelevt, this.wheelHandle);
    },
    beforeDestroy() {
        //取消监听
        this.$refs.maskBox.removeEventListener(
            this.mousewheelevt,
            this.wheelHandle
        );
    },
    created() {
        this.handleReset();
    },
    methods: {
        /**
         *
         * 下載圖片
         * **/

        downloadByBlob(url, name) {
            let image = new Image();
            image.setAttribute("crossOrigin", "anonymous");
            image.src = url;
            image.onload = () => {
                let canvas = document.createElement("canvas");
                canvas.width = image.width;
                canvas.height = image.height;
                let ctx = canvas.getContext("2d");
                ctx.drawImage(image, 0, 0, image.width, image.height);
                canvas.toBlob((blob) => {
                    let url = URL.createObjectURL(blob);
                    this.download(url, name);
                    // 用完释放URL对象
                    URL.revokeObjectURL(url);
                });
            };
        },
        download(href, name) {
            let eleLink = document.createElement("a");
            eleLink.download = name;
            eleLink.href = href;
            eleLink.click();
            eleLink.remove();
        },

        /**
         * 重置
         */
        handleReset() {
            this.imgW = 0;
            this.imgH = 0;
            this.top = 0;
            this.left = 0;
            this.deg = 0;
            this.scale = "scale(1)";
            this.size = 0;
            this.initImage();
        },
        /**
         * 获取图片的url
         * @param {string} url
         */
        getImgSize(url) {
            return new Promise((resolve, reject) => {
                let imgObj = new Image();
                imgObj.src = url;
                imgObj.onload = () => {
                    resolve({
                        width: imgObj.width,
                        height: imgObj.height,
                    });
                };
            });
        },
        /**
         * 初始化图片
         */
        async initImage() {
            if (!this.imageUrl) {
                return;
            }
            let { width, height } = await this.getImgSize(this.imageUrl);
            // 设置原始图片的大小
            let realWidth = width;
            let realHeight = height;

            // 获取高宽比例
            const whRatio = realWidth / realHeight;
            const hwRatio = realHeight / realWidth;

            //获取盒子的大小
            const boxW = this.$refs.maskBox.clientWidth;
            const boxH = this.$refs.maskBox.clientHeight;

            if (realWidth >= realHeight) {
                this.imgH = hwRatio * boxW;
                const nih = this.imgH;
                if (nih > boxH) {
                    this.imgH = boxH;
                    this.imgW = whRatio * boxH;
                } else {
                    this.imgW = boxW;
                }
                this.top = (boxH - this.imgH) / 2;
                this.left = (boxW - this.imgW) / 2;
            } else {
                this.imgW = (boxH / realHeight) * realWidth;
                this.imgH = boxH;
                this.left = (boxW - this.imgW) / 2;
            }
        },
        imgScaleHandle(zoom) {
            this.size += zoom;
            if (this.size < -0.5) {
                this.size = -0.5;
            }
            this.scale = `scale(${1 + this.size}) rotateZ(${this.deg}deg)`;
        },
        /**
         * 鼠标滚动 实现放大缩小
         */
        wheelHandle(e) {
            e.preventDefault();
            const ev = e || window.event; // 兼容性处理 => 火狐浏览器判断滚轮的方向是属性 detail,谷歌和ie浏览器判断滚轮滚动的方向是属性 wheelDelta
            // dir = -dir; // dir > 0 => 表示的滚轮是向上滚动,否则是向下滚动 => 范围 (-120 ~ 120)
            const dir = ev.detail ? ev.detail * -120 : ev.wheelDelta;
            //滚动的数值 / 2000 => 表示滚动的比例,用此比例作为图片缩放的比例
            this.imgScaleHandle(dir / 2000);
        },
        /**
         * 处理图片拖动
         */
        onmousedownHandle(e) {
            const that = this;
            this.$refs.maskBox.onmousemove = function (el) {
                const ev = el || window.event; // 阻止默认事件
                ev.preventDefault();
                that.left += ev.movementX;
                that.top += ev.movementY;
            };
            this.$refs.maskBox.onmouseup = function () {
                // 鼠标抬起时将操作区域的鼠标按下和抬起事件置为null 并初始化
                that.$refs.maskBox.onmousemove = null;
                that.$refs.maskBox.onmouseup = null;
            };
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                return false;
            }
        },
    },
};
</script>

<style lang="scss" scoped>
.world_map {
    width: 1200px;
    margin: 41px auto;

    .name {
        width: 95px;
        margin: 0 auto;
        font-size: 22px;
        font-family: "st";
        font-weight: bold;
        color: pink;
        line-height: 30px;
        letter-spacing: 1px;
    }
}

.watchMap {
    width: 1200px;
    height: 662px;
    background: pink;
    position: relative;
    // overflow: hidden;
    margin-left: 360px;

    .imgBox {
        width: 100%;
        height: 100%;
        overflow: hidden;
        position: relative;

        img {
            cursor: move;
            position: absolute;
        }
    }

    .Tools {
        width: 43px;
        min-height: 100px;
        position: absolute;
        right: -50px;
        top: 0;
        user-select: none;

        .Tools-item {
            width: 100%;
            height: 44px;
            background: pink;
            margin-bottom: 5px;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;

        }

        .Tools-item:hover{
            background-color: red;
            color: #fff;
        }
    }
}
</style>

效果:@韩桑文章来源地址https://www.toymoban.com/news/detail-519207.html

vue图片放大缩小拖动,vue.js,javascript,前端,Powered by 金山文档

到了这里,关于vue项目实现图片缩放与拖拽功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包