elementui+js+vue——实现图片组件的封装

1. 实现图片的放大缩小
2. 实现图片的拖动功能
3. 实现图片的预览

最近同事在写一个关于 图片放大缩小拖动的功能,其实不止是图片,只要是在以下组件中的内容,都是可以支持放大缩小拖动的。
功能:

1.鼠标拖动:拖动改变位置
2.鼠标滚动:实现放大缩小功能
3.根据是否有图片,展示三种不同的效果

一:先上效果图:

1.没有内容的时候

在这里插入图片描述

2.有一张图片的时候

在这里插入图片描述

3.有两张图片的时候

在这里插入图片描述

二:分析组件

首先是一个弹层,可以使用el-dialog组件才处理,其次,根据图片的数量,分为 0张图片/1张图片/2张图片等。

三: inc_imgsvg.vue组件的封装

1.html部分的代码
<template>
  <div class="drag-outer"
       ref="dragWrap"
       :style="'width:'+(imgWidth=='auto'?'calc(50% - 10px)':imgWidth)"
       @mouseenter="isHover = true"
       @mouseleave="isHover = isMousedown = false"
       @mousemove="dragMousemove">
    <div class="drag-inner"
         ref="dragElement"
         @mousedown="dragMousedown"
         @mouseup.stop="isMousedown = false">
      <slot></slot>
    </div>
  </div>
</template>
2.script部分的代码
<script>
export default {
  name: 'inc_imgsvg',
  props: {
    imgWidth: {
      type:String,
      default () {
        return '400px'
      }
    },
    scaleZoom: {
      type: Object,
      default () {
        return {
          max: 5,
          min: 0.2
        }
      }
    }
  },
  data() {
    return {
      isMousedown: false,
      isHover: false,
      moveStart: {},
      translate: {x: 0, y: 0},
      scale: 1
    }
  },
  methods: {
    handleScroll(e) {
      if(this.isHover) {
        let speed = e.wheelDelta/120
        if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) {
          this.scale+=0.2*speed
          this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
        }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){
          this.scale+=0.2*speed
          this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
        }
      }
    },
    dragMousedown() {
      this.moveStart.x = event.clientX
      this.moveStart.y = event.clientY
      this.isMousedown = true
    },
    dragMousemove() {
      if(this.isMousedown) {
        this.translate.x += (event.clientX - this.moveStart.x) / this.scale
        this.translate.y += (event.clientY - this.moveStart.y) / this.scale
        this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
        this.moveStart.x = event.clientX
        this.moveStart.y = event.clientY
      }
    }
  },
  mounted() {
    window.addEventListener('mousewheel',this.handleScroll,false)
  }
}
</script>
3.css部分的代码
<style lang="scss" scoped>
.drag-outer {
  overflow: hidden;
  height:500px; float: left;
  display: flex;
  background-color:#fff;
  justify-content: center;
  align-items: center;
  .drag-inner {
    transform-origin: center center;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: move;
    user-select: none;
    width:100%;
    height:100%;
    >* {
      -webkit-user-drag: none;
      user-drag: none;
    }
    img{object-fit:contain; width:100%; height:100%}
  }
}
</style>

四:组件的使用

1.弹层的代码——html部分
<template>
  <el-dialog class="boxEDA" title="查看EDA模型信息" :visible.sync="show" width="80%" :before-close="handleClose">
    <div class="imgs" :class="{no:!showImg}" v-loading="load">
      <template v-if="showImg">
        <inc_imgsvg v-if="this.edaInfo.thumbnail" :imgWidth="this.edaInfo.ethumbnail?'auto':'100%'">
          <img :src="edaInfo.thumbnail" alt="">
        </inc_imgsvg>
        <inc_imgsvg v-if="this.edaInfo.ethumbnail" :imgWidth="this.edaInfo.thumbnail?'auto':'100%'">
          <img :src="edaInfo.ethumbnail" alt="">
        </inc_imgsvg>
      </template>
      <el-empty v-if="!showImg" description="暂无信息"></el-empty>
    </div>
    <p class="note" v-if="showImg">支持鼠标点击拖拽、鼠标滚轮放大缩小操作</p>
  </el-dialog>
</template>
2.弹层的代码——script部分
<script>
import {searchSvc} from "@/api";
import inc_imgsvg from "@/pages/componentDetailCloud/inc_imgsvg";

export default {
  name: "inc_showeda",
  components: {inc_imgsvg},
  props:['show','currentId'],
  data(){
    return{
      load:false,pid:'',
      edaInfo:{},
      showImg:false,
    }
  },
  mounted() {
    this.load = true;
    searchSvc.componentApi.getComponentFindSchById(this.currentId).then(res=>{
      this.edaInfo = res.data;
      this.showImg = res.data.thumbnail || res.data.ethumbnail;
    }).finally(()=>{
      this.load = false;
    })
  },
  methods: {
    handleClose() {
      this.$parent.showEDA = false;
    },
  }
}
</script>
3.弹层的代码——css部分
<style scoped lang="scss">
.boxEDA ::v-deep .el-dialog__body{background-color:#eee;
  .imgs{overflow: hidden; display:flex; justify-content:space-between;}
  .imgs.no{background-color:#fff; justify-content: center}
}
.note{display: block; padding:1em 0 0 0; margin:0; color:#999; text-align: center}
</style>

完成!!!多多积累,多多收获!!!

Logo

前往低代码交流专区

更多推荐