Vue3 实现图片滚轮缩放拖拽组件

下面将采用Vue3的语法讲述如何实现在一定区域内用鼠标滚轮缩放图片以及在该区域内拖拽图片,在下面的应用里还会使用到父子组件传值,调用方法,以及compute计算,自定义指令等
效果图:

图片缩放拖拽

由父组件和子组件完成

父组件html

  <div class="box1">
     <imgbox  :configImgData="imgData" @scaleImgFun="scaleImgFun"></imgbox>
 </div>

父组件js

<script lang="ts" setup>
  import imgbox from './imgbox.vue' //拖拽,放大缩小图片  子组件
   const imgData = reactive({
    
    
        imgSrc: 'xxx.png',
        scale:1,//默认缩放1
    })
   const scaleImgFun = (type)=>{
    
    //缩放图片
      switch (type) {
    
    
          case 'large': imgData.scale += 0.1; break;
          case 'small': if(imgData.scale >= 0.1) imgData.scale -= 0.1; break;
      }
  	}
</script>

父组件css

 .box1{
    
    
    width: 100%;
    height: 500px;
    overflow: hidden;
  }

子组件imgBox.vue html

 <div class="myDiv">
    <img class="dragImg" ref="img" name="removeimg" :src="configImgData.imgSrc" v-drag :style="scaleFun" @mousewheel="rollImg()">
     <div class="btnbox">
         <i style="margin-bottom: 20px;" class="iconfont icon-add operchange" @click="scaleImgFun('large')"></i>
         <i class="iconfont icon-jianhao operchange" @click="scaleImgFun('small')"></i>
     </div>
 </div>

子组件imgBox.vue js

<script lang="ts" setup>
    import {
    
    ref,reactive,onMounted,computed} from 'vue'
    //接收父组件传值
    interface Props{
    
    
        configImgData: Object
    }
    const props = withDefaults(defineProps<Props>(), {
    
    
        configImgData: () => {
    
    return {
    
    }}
    })
  
  	//vue3计算属性
    const  scaleFun = computed(()=> {
    
    
        return `transform:scale(${
     
     props.configImgData.scale})`
    })
    //调用父组件方法
    const emit = defineEmits<{
    
    
        (event: "scaleImgFun", data: string): void
    }>()
    const scaleImgFun = (type)=>{
    
    //点击放大//点击缩小
        emit('scaleImgFun', type)
    }
    //滚轮缩放
    const rollImg = () => {
    
    
        if(event.wheelDelta > 0){
    
     //放大
            emit('scaleImgFun', 'large')
        }else{
    
    //缩小
            emit('scaleImgFun', 'small')
        }
    }


	//自定义指令
    const vDrag = {
    
     //必须以 vNameOfDirective 的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。
        beforeMount: (el) => {
    
    
            // 在元素上做些操作
            let dragBox = el; //获取当前元素
            dragBox.onmousedown = e => {
    
    
                e.preventDefault();
                //算出鼠标相对元素的位置
                let disX = e.clientX - dragBox.offsetLeft;
                let disY = e.clientY - dragBox.offsetTop;
                document.onmousemove = e => {
    
    
                    //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
                    e.preventDefault();
                    let left = e.clientX - disX;
                    let top = e.clientY - disY;
                    //移动当前元素
                    dragBox.style.left = left + "px";
                    dragBox.style.top = top + "px";
                };
                document.onmouseup = e => {
    
    
                    e.preventDefault();
                    //鼠标弹起来的时候不再移动
                    document.onmousemove = null;
                    //预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
                    document.onmouseup = null;
                };
            }
        }
    }
</script>

子组件imgBox.vue css

扫描二维码关注公众号,回复: 14628361 查看本文章
<style  lang="less">
    .myDiv{
    
    
        width: 100%;
        height: 100%;
        position: relative;
        overflow: hidden;
        display: flex;
        justify-content: center;
        .dragImg{
    
    
            width: auto;
            height: 100%;
            position: absolute;
            margin: 0 auto;
            display: block;
        }
        .btnbox{
    
    
            position: absolute;
            right: 10px;
            top: calc((100% - 100px) / 2);
            z-index: 99;
        }
        .operchange{
    
    //按钮的大小
            font-size: 40px;
            display: block;
            color: #10A4FA;
            cursor: pointer;
        }
    }
</style>

猜你喜欢

转载自blog.csdn.net/qq_37656005/article/details/125807702