vue项目中js如何实现以鼠标为中心放大缩小图片,拖拽移动功能

记录下如何实现以鼠标为中心放大缩小图片,拖拽移动功能,以后可能用得到,实现这个功能首先用到了4个事件,分别是mousewheel、mousedown、mousemove、mouseup,并使用ref拿到实例

domo代码:

<div class="content" ref="content">
      <div class="body-content"
      ref="bigImage"
      @mousewheel.prevent="rollImg"
      @mousedown.prevent="bodydown"
      @mousemove.prevent="bodymove"
      @mouseup.stop="bodyup"
      </div>
 </div>

data定义:

startPoint: {
    x: 0,
    y: 0
},
isDown: false,
prevTranslateMap: {
    x: 0,
    y: 0
}, // 记录translate坐标值
    initWidth: undefined, // 原始宽度
    initHeight: undefined, // 原始高度
    scale: 1, // 初始化缩放比
    option: {
        interval: 0.1, // 每次叠加的间隔数
        minScale: 0.8, // 最小缩放
        maxScale: 3 // 最大缩放
      }

方法:

    rollImg(e) {
      const zoomDom = this.$refs.bigImage[this.previewIndex];
      const isZoomOut = e.deltaY < 0; // 缩小
      const { x: mouseX, y: mouseY } = e; // 鼠标坐标
      // 获取元素宽高
      const { height, width } = zoomDom.getBoundingClientRect();
      const pDom = zoomDom.parentElement;
       const { top: pTop, left: pLeft } = pDom.getBoundingClientRect();
       if (isZoomOut) {
         // 缩小
         this.scale -= this.option.interval;
         if (this.option.minScale && this.scale < this.option.minScale) {
           this.scale = this.option.minScale;
         }
       } else {
         // 放大
         this.scale += this.option.interval;
         if (this.option.maxScale && this.scale > this.option.maxScale) {
           this.scale = this.option.maxScale;
         }
       }
      //  获取比例
        const yScale = (mouseY - pTop - this.prevTranslateMap.y) / height;
        const xScale = (mouseX - pLeft - this.prevTranslateMap.x) / width;
        // 放大之后的宽高
        const ampWidth = this.initWidth * this.scale;
        const ampHeight = this.initHeight * this.scale;
        // 重新计算坐标
        const y = yScale * (ampHeight - height);
        const x = xScale * (ampWidth - width);
        const translateY = this.prevTranslateMap.y - y;
        const translateX = this.prevTranslateMap.x - x;
        zoomDom.style.transform = `translate(${translateX}px, ${translateY}px) scale(${this.scale})`;
        this.prevTranslateMap = {
            x: translateX,
            y: translateY
        };
        e.preventDefault();
    },
    bodydown(e) {
      const zoomDom = this.$refs.content;
      const disX = e.clientX - zoomDom.offsetLeft;
      const disY = e.clientY - zoomDom.offsetTop;
      this.isDown = true;
      this.startPoint = { x: disX, y: disY };
    },
    bodymove(event) {
      const zoomDom = this.$refs.content;
      if (this.isDown === false) {
        return;
      }
        this.left = event.clientX - this.startPoint.x;
        this.top = event.clientY - this.startPoint.y;
        zoomDom.style.left = `${this.left}px`;
        zoomDom.style.top = `${this.top}px`;
    },
    bodyup() {
      this.isDown = false;
    }

© 版权声明
THE END
喜欢就支持以下吧
点赞0赞赏
分享
评论 抢沙发