自定义vue图片预览缩放组件

<template>
    <div id='zoompic'>
        <div class="zoom-img">
            <img ref="Img" :src="imgurl" @mousedown="move">
            <span class="closeIcon" @click="closeModal" v-if="shwClo">&times;</span>
        </div>
    </div>
</template>

<script>
export default {
    name: '',
    props: {
        imgurl:''
    },
    components: {

    },
    data() {
        return {
            shwClo:true,//是否显示关闭按钮
            isMove:false,//是否可移动
            eLeft:0,
            eTop:0
        };
    },
    computed: {

    },
    created() {

    },
    mounted() {
        this.initImg();
    },
    activated() {//该钩子在进入当前路由时执行

    },
    deactivated (){//该钩子在离开当前路由时执行

    },
    watch: {

    },
    methods: {
        closeModal(){
            this.$emit('close',true);
        },
        move(e){
            this.shwClo = false;
            e.preventDefault();
            e.stopPropagation();
            let odiv = e.target;//获取目标元素
            let curtdv = e.target.parentElement;//获取目标元素的父元素
            let disX,disY;
            if(curtdv.className == 'close-zoom')return;
            this.isMove = true;//按下才能移动
            //记录鼠标相对元素的位置
            disX = e.clientX - this.eLeft;
            disY = e.clientY - this.eTop;
            document.onmousemove = (e)=>{ //鼠标按下并移动的事件
                e.preventDefault();
                e.stopPropagation();
                if(this.isMove){
                //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
                this.eLeft = e.clientX - disX;
                this.eTop = e.clientY - disY;
                //移动当前元素
                //方式一:(需设置元素为绝对定位)
                // odiv.style.left = this.eLeft + 'px';
                // odiv.style.top = this.eTop + 'px';

                //方式二:
                curtdv.style.webkitTransform = 'translate('+this.eLeft+'px,'+this.eTop+'px)';
                }else return;
            };
            document.onmouseup = (e) => {
                console.log("弹起");
                this.shwClo = true;
                this.isMove = false;
                document.onmousemove = null;
                document.onmousedown = null;
            };
        },
        //滚轮事件
        fnWheel(obj,callback){
            obj.onmousewheel = fn;
            if (obj.addEventListener) {
                obj.addEventListener('DOMMouseScroll', fn, false);
            };
            function fn(ev) {
                var oEvent = ev || window.event;
                var down = true;
                if (oEvent.detail) {
                    down = oEvent.detail > 0
                } else {
                    down = oEvent.wheelDelta < 0
                }
                if (callback) {
                    callback.call(this, down, oEvent);
                }
                if (oEvent.preventDefault) {
                    oEvent.preventDefault();
                }
                return false;
            };
        },
        initImg(){
            const winWidth = window.innerWidth;
            let oImg = this.$refs.Img;
            this.fnWheel(oImg,function(down, oEvent){
                var oldWidth = this.offsetWidth;
                var oldHeight = this.offsetHeight;
                var oldLeft = this.offsetLeft;
                var oldTop = this.offsetTop;
                var scaleX = (oEvent.clientX - oldLeft) / oldWidth; //比例
                var scaleY = (oEvent.clientY - oldTop) / oldHeight;
                if (down) {
                    if(this.offsetWidth < 60) return;//限制缩小尺寸
                    this.style.width = this.offsetWidth * 0.9 + "px";
                    this.style.height = this.offsetHeight * 0.9 + "px";
                } else {
                    if(this.offsetWidth >= winWidth*0.7) return;//限制最大尺寸
                    this.style.width = this.offsetWidth * 1.1 + "px";
                    this.style.height = this.offsetHeight * 1.1 + "px";
                }
                var newWidth = this.offsetWidth;
                var newHeight = this.offsetHeight;
                this.style.left = oldLeft - scaleX * (newWidth - oldWidth) + "px";
                this.style.top = oldTop - scaleY * (newHeight - oldHeight) + "px";
            })
        }
    }
};
</script>

<style lang="scss">
#zoompic{
    position: fixed;
    top: 0;
    left: 0;
    z-index:999;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.4);
    user-select: none;
    display: flex;
    justify-content: center;
    align-items: center;
    .zoom-img {
        max-width: 80vw;
        max-height: 80vh;
        position: relative;
        .closeIcon {
            width: 50px;
            height: 50px;
            font-size: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            background: rgba(0,0,0,.5);
            position: absolute;
            border-radius: 50%;
            top: -20px;
            right: -20px;
        }
        img {
            width: 300px;
        }
    }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值