Bootstrap

Vue中实现滚轮滑动放大图片并可进行拖动(封装好的组件,可直接使用)

 效果图

DEMO

组件(子组件改为自己的路径和名称)

<template>
    <div class="box">
      <ImageViewr ref="ImageViewrRef" :imageUrl="url" />
      <button @click="reset">重置</button>
    </div>
</template>
<script>
import ImageViewr from './components/ImageViewr.vue'
export default {
    data() {
        return {
            url:'https://yaoliangliang-oss.oss-cn-beijing.aliyuncs.com/efa6c859-83cd-4749-89e3-667bbcebbd03.jpg'
        }
    },
    methods: {
      reset(){
          this.$refs.ImageViewrRef.resetImage();
      }
    },
    components:{ImageViewr,},
    computed:{},
    watch:{},
    created() {},
}
</script>
<style lang="scss" scoped>
.box{
  width: 500px;
  height: 400px;
  border: 1px solid red;
}
button{
  position: absolute;
  top: 320px;
}
</style>

子组件 

<template>
  <div class="imageView" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseleave="onMouseUp" @mouseup="onMouseUp">
    <img :src="imageUrl" ref="image" @wheel="onWheel">
  </div>
</template>

<script>
export default {
  props: {
    imageUrl: {
      type: String,
      require: true,
    },
  },
  data() {
    return {
      currentScale: 1,// 当前缩放比例
      isDragging: false,// 是否正在拖拽图片
      startX: 0, // 拖拽起始点x坐标
      startY: 0, // 拖拽起始点y坐标
      translateX: 0, // 图片平移x方向距离
      translateY: 0, // 图片平移y方向距离
      dragSpeed: 0.3,// 拖拽速度
      zoomSpeed: 0.1, //控制缩放速度
      maxScale: 5, //最大缩放值
      minScale: 0.1, //最小缩放值
    };
  },
  methods: {
    // 鼠标按下事件处理函数
    onMouseDown(e) {
      e.preventDefault();
      this.isDragging = true;
      this.startX = e.clientX;
      this.startY = e.clientY;
      this.$refs.image.style.cursor = "grabbing";
    },
    // 鼠标移动事件处理函数
    onMouseMove(e) {
      if (!this.isDragging) return;
      const deltaX = (e.clientX - this.startX) * this.dragSpeed;
      const deltaY = (e.clientY - this.startY) * this.dragSpeed;
      this.translateX += deltaX;
      this.translateY += deltaY;
      this.$refs.image.style.transform = `scale(${this.currentScale}) translate(${this.translateX}px, ${this.translateY}px)`;
      this.startX = e.clientX;
      this.startY = e.clientY;
    },
    // 鼠标松开事件处理函数
    onMouseUp() {
      this.isDragging = false;
      this.$refs.image.style.cursor = "grab";
    },
    // 鼠标滚轮事件处理函数
    onWheel(e) {
      e.preventDefault();
      const delta = e.deltaY > 0 ? -1 : 1;
      this.currentScale = Math.min(this.maxScale, Math.max(this.minScale, this.currentScale + delta * this.zoomSpeed));
      this.$refs.image.style.transform = `scale(${this.currentScale}) translate(${this.translateX}px, ${this.translateY}px)`;
    },
    // 重置图片缩放和移动
    resetImage() {
      this.currentScale = 1;
      this.translateX = 0;
      this.translateY = 0;
      this.$refs.image.style.transform = "scale(1) translate(0, 0)";
    },

  },
};
</script>

<style lang="scss" scoped>
.imageView {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.imageView .elImageclass {
  width: 100%;
  height: 100%;
  touch-action: none;
  user-drag: none;
  -webkit-user-drag: none;
}

img {
  width: 100%;
  height: 100%;
  cursor: grab;
  object-fit: contain !important;
}
</style>

;