vue 图片拖拽移动缩放

  • Post author:
  • Post category:vue


问题描述:因”Viewer“插件功能在软件内嵌入的web页面不兼容,无法移动。(IE内核)由于调试困难,浏览器运行正常,软件中无法使用,不报错捕获不到异常;然后各种查询资料各种造轮子,最终完成了功能;


– **代码**

在页面引入组件

<previewPicture  :imgUrl=”showFileList.Url” :src=”showFileList.Url”></previewPicture>

对应组件代码

  <div class="main">
    <div ref="palnbox" class="paln-box">
      <div
        class="movableItem"
        :style="{width:width,height:height}"
        @mousewheel="rollImg($event)"
        @mousedown="drag($event,1)"
	    @DOMMouseScroll="rollImg($event)"
        ref="bigImage"
      >
        <!-- 图片不可选中 或不可拖拽到新标签打开-->
        <img
          :src="src"
          oncontextmenu="return false;"
          onselectstart="return false;"
          draggable="false"
          alt
        />
       </div>
    </div>
</div>

style样式代码

<style lang="scss" scoped>
.main {
  width: 100%;
  height: 100%;
  .paln-box{
    width: 100%;
    height: 100%;
    position: relative;
   .movableItem {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, 0%);
      img {
        z-index: 1;
        width: 100%;
        height: 100%;
      }

      .equipment {
        position: absolute;
        top: 0;
        left: 0;
        transform: translate(-50%, -50%);
        z-index: 2;
        font-size: 40px;
        // color: red;
        // background: blue;
        zoom: 1;
      }
    }
 }
}
</style>

js对应代码

export default {
  props: {
    src: String,
    equipment: {
      type: Array,
      default: () => {
        return [
          {
            iconImgUrl: "",
            top: 0,
            left: 0
          }
        ];
      }
    },
    isEdit: {
      default: false
    },
    imgUrl: {}
  },
data(){
  return{
      // 定时器
      timer: "",
      // 图片加载失败
      imgOnerror: false,
      imgIndex: 0,
      isChange: true,
      // 图片显示默认大小
      width: "1000px",
      height: "600px",
      // 可缩小倍数,为空则可无限缩小
      minification: 3,
      // 可放大倍数 为空则可无限放大
      magnification: "",
      bigMaxWidth: 1600,
      bigMaxHeight: 800,

      // 小图标信息
      iconImgUrl: "",
      iconWidth: "",
      // 存储每个小图标处理好的宽高
      iconHeight: "",
      arrIcon: [],
      iconMaxWidth: 32,
      iconMaxHeight: 32,
       }
     },
mounted() {
    // console.log(this.imgUrl);
    //   console.log(this);
    this.getImgInfo(
      this.imgUrl,
      this.bigMaxWidth,
      this.bigMaxHeight,
      "width",
      "height"
    );
    if (this.equipment.length != 0) {
      this.arrIcon = [];
      let finish = true;
      this.equipment.filter(item => {
        if (!item.iconImgUrl) {
          finish = false;
        }
        return true;
      });
      console.log("finish", finish);
      if (finish) {
        this.equipment.filter((item, index) => {
          if (index >= this.imgIndex) {
            console.log("iconImgUrl", this.equipment[index].iconImgUrl);
            this.getImgInfo(
              this.$baseUrl + item.iconImgUrl,
              this.iconMaxWidth,
              this.iconMaxHeight,
              "iconWidth",
              "iconHeight",
              true,
              "arrIcon"
            );
          }
          console.log("22filter", index);
          return true;
        });
      }
    }

    this.iconImgUrl = JSON.parse(
      JSON.stringify(this.$baseUrl + this.equipment[0].iconImgUrl)
    );
    //console.log("imgUrl", this.imgUrl);
    //console.log("equipment", this.equipment);
  },
  methods: {
       getImgInfo(
      imgUrl,
      MaxWidth,
      MaxHeight,
      StrWidth,
      StrHeight,
      Array = false,
      arr,
      num = 0
    ) {
      // console.log("objWidthName", this[StrWidth], this[StrHeight]);
      var img = new Image();
      var oImg = this.$refs.bigImage.childNodes[0];
      img.src = imgUrl;
      if (
        img.width > document.body.clientWidth ||
        img.height > document.body.clientHeight
      ) {
        this.width = document.body.clienWidth * 0.8;
        this.height = document.body.clientHeight * 0.8;
      } else {
        this.width = img.width;
        this.height = img.height;
      }
      // alert(document.body.clientHeight)
      //  alert( this.height)
      let _this = this;
      img.onerror = () => {
        // console.log("加载失败!!", _this.arrIcon.length);
        // console.log(imgUrl, MaxWidth, MaxHeight, StrWidth, StrHeight);
        _this.imgOnerror = true;
        _this.imgIndex =
          _this.arrIcon.length - 1 < 0 ? 0 : _this.arrIcon.length - 1;
        this.timer = setTimeout(() => {
          if (num <= 5) {
            _this.getImgInfo(
              imgUrl,
              MaxWidth,
              MaxHeight,
              StrWidth,
              StrHeight,
              Array,
              arr,
              num + 1
            );
          }
          clearInterval(this.timer);
        }, 2000);
      };
      img.onload = function(e) {
        //  显示时 初始 最大宽度
        let maxWidth = MaxWidth;
        //  显示时 初始 最大高度
        let maxHeight = MaxHeight;
        let imgref = oImg;
        if (
          //   e.path[0].naturalWidth <= maxWidth &&
          //   e.path[0].naturalHeight <= maxHeight
          // 这个地方 e.path 在ie浏览器里面是没有的 要重视 然后我查了资料有个函数兼容,但是我在我的代码运行软件环境 压根不生效  只有直接上手refdom去操作  具体的可以打印出来在ie 谷歌比较
          imgref.naturalWidth <= maxWidth &&
          imgref.naturalHeight <= maxHeight
        ) {
          _this[StrWidth] = imgref.naturalWidth + "px";
          _this[StrHeight] = imgref.naturalHeight + "px";
        } else {
          _this[StrWidth] = imgref.naturalWidth + "px";
          _this[StrHeight] = imgref.naturalHeight + "px";
          if (
            imgref.naturalWidth > maxWidth &&
            imgref.naturalHeight <= maxHeight
          ) {
            let ratio = imgref.naturalWidth / imgref.naturalHeight;
            _this[StrWidth] = "1600px";
            _this[StrHeight] = maxWidth / ratio + "px";
          } else if (
            imgref.naturalWidth <= maxWidth &&
            imgref.naturalHeight > maxHeight
          ) {
            let ratio = imgref.naturalWidth / imgref.naturalHeight;
            _this[StrWidth] = maxHeight * ratio + "px";
            _this[StrHeight] = "800px";
          } else if (
            imgref.naturalWidth > maxWidth &&
            imgref.naturalHeight > maxHeight
          ) {
            let ratio = imgref.naturalWidth / imgref.naturalHeight;
            let w = maxWidth;
            let h = w / ratio;
            if (h > maxHeight) {
              let ratio2 = w / h;
              h = maxHeight;
              w = h * ratio2;
            }
            _this[StrWidth] = w + "px";
            _this[StrHeight] = h + "px";
          }
        }
        if (Array) {
          _this[arr].push({
            iconWidth: _this[StrWidth],
            iconHeight: _this[StrHeight]
          });
          console.log(
            "tow#################################arrIcon",
            _this[arr].length
          );
        }
        // _this[StrWidth] = `${e.path[0].naturalWidth}px`;
        // _this[StrHeight] = `${e.path[0].naturalHeight}px`;
        // vm.$set(vm.imgInfo, "width", img.width);
        // vm.$set(vm.imgInfo, "height", img.height);
        // console.log("打印图片信息", imgUrl, _this[StrWidth], _this[StrHeight]); // 打印图片信息

        // console.log("打印图片信息", e.path[0].naturalHeight); // 打印图片信息
        // console.log("打印图片信息", e); // 打印图片信息
        // console.log("打印图片信息this.width", _this[StrWidth]); // 打印图片信息
        // console.log("打印图片信息this.height", _this[StrHeight]); // 打印图片信息
      };
    },
    // 缩放
    rollImg() {
      // var oImg = document.getElementsByClassName("movableItem")[0];
      var oImg = this.$refs.bigImage;
      // console.log(
      //   "length",
      //   document.getElementsByClassName("movableItem").length
      // );
      // console.log("oImg", oImg);
      var _this = this;
      function fnWheel(obj, fncc) {
        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 (fncc) {
            fncc.call(this, down, oEvent);
          }
          if (oEvent.preventDefault) {
            oEvent.preventDefault();
          }
          return false;
        }
      }
      fnWheel(oImg, function(down, oEvent) {
        var oldWidth = this.offsetWidth;
        var oldHeight = this.offsetHeight;
        var oldLeft = this.offsetLeft;
        var oldTop = this.offsetTop;
        // console.log(oEvent);
        // var parent = oEvent.target.childNodes[2];
        // 获取父元素距离页面可视区域的位置
        // var parentLeft = parent.getBoundingClientRect().left;
        // var parentTop = parent.getBoundingClientRect().top;
        // console.log(oImg);

        var imgref = oImg.childNodes[0];

        var parentLeft = imgref.getBoundingClientRect().left;
        var parentTop = imgref.getBoundingClientRect().top;
        // 比例 = (点击位置距离可视窗口位置 - 父元素距离可视窗口位置 - 相对定位的left)/ 本身宽度
        var scaleX = (oEvent.clientX - parentLeft - oldLeft) / oldWidth; //比例
        var scaleY = (oEvent.clientY - parentTop - oldTop) / oldHeight;

        let nowWidth = this.style.width.split("p")[0];
        // console.log("nowWidth:" + nowWidth);
        let initWidth = _this.width.split("p")[0];
        let initHeight = _this.height.split("p")[0];

        let miniFlag = true;
        let magniFlag = true;
        if (_this.minification) {
          // 限制缩小范围
          if (nowWidth <= parseInt(initWidth / _this.minification)) {
            miniFlag = false;
            // console.log("限制缩小范围");
            // console.log(
            //   "限制缩小范围",
            //   nowWidth,
            //   parseInt(initWidth / _this.minification)
            // );
            this.style.width = parseInt(initWidth / _this.minification) + "px";
            this.style.height =
              parseInt(initHeight / _this.minification) + "px";
          }
          if (_this.magnification) {
            // 限制放大范围
            if (nowWidth >= parseInt(initWidth * _this.magnification)) {
              magniFlag = false;
              // console.log("限制放大范围");
              this.style.width =
                parseInt(initWidth * _this.magnification) + "px";
              this.style.height =
                parseInt(initHeight * _this.magnification) + "px";
            }
          }
        }

        if (down && miniFlag) {
          console.log("缩小");
          this.style.width = parseInt(this.offsetWidth * 0.9) + "px";
          this.style.height = parseInt(this.offsetHeight * 0.9) + "px";
        } else if (!down && magniFlag) {
          console.log("放大");
          this.style.width = parseInt(this.offsetWidth * 1.1) + "px";
          this.style.height = parseInt(this.offsetHeight * 1.1) + "px";
        }
        var newWidth = this.offsetWidth;
        var newHeight = this.offsetHeight;

        // 新的相对位置left = 原先的相对位置left - 比例 *(本身新的宽度-旧的宽度)
        this.style.left =
          Math.round(this.offsetLeft - scaleX * (newWidth - oldWidth)) + "px";
        this.style.top =
          Math.round(this.offsetTop - scaleY * (newHeight - oldHeight)) + "px";
      });
    },
    //拖拽
    drag(ev) {
      // var ie = document.all;
      //   console.log(ev / 0);
      var _this = this;
      console.log("点击图片");
      var nn6 = document.getElementById && !document.all;
      var isdrag = false;
      var y, x;
      var nTY, nTX;
      var oDragObj;
      function moveMouse(e) {
        //   console.log(event.clientY - y);
        // console.log("oDragObj.style.top1", oDragObj.style.top);
        if (isdrag) {
          oDragObj.style.top =
            (nn6 ? nTY + e.clientY - y : nTY + event.clientY - y) + "px";
          oDragObj.style.left =
            (nn6 ? nTX + e.clientX - x : nTX + event.clientX - x) + "px";
          // console.log("oDragObj.style.top2", oDragObj.style.top);
          // console.log(`nTY+e.clientY-y=${nTY}+${e.clientY}-${y}`);
          // console.log(`nTY+e.clientY-y=${nTY + e.clientY - y}`);

          return false;
        }
      }
      function initDrag(e) {
        console.log("点击图片initDrag");
        var oDragHandle = nn6 ? e.target : event.srcElement;

        var oImg = _this.$refs.bigImage.childNodes[0];

        var topElement = "HTML";

        while (
          oDragHandle.tagName != topElement &&
          oDragHandle.className != "movableItem"
        ) {
          oDragHandle = nn6
            ? oDragHandle.parentNode
            : oDragHandle.parentElement;
        }
        if (oDragHandle.className == "movableItem") {
          isdrag = true;
          oDragObj = oDragHandle;
          // 父元素宽高
          //   console.log(e);
          //   console.log(e.path[2]);
          //   let width = e.path[2].offsetWidth;
          //   let height = e.path[2].offsetHeight;

          //   let widthItem = oImg.style.offsetWidth;
          //   let heightItem = oImg.style.offsetHeight;
          let width = _this.$refs.palnbox.offsetWidth;
          let height = _this.$refs.palnbox.offsetHeight;
          // console.log(width, height);
          // console.log(oDragObj.style);
          // 这里判断第一次获取不到style 样式 默认为 居中50%
          if (oDragObj.style.top == "") {
            // console.log(
            //   '进入了oDragObj.style.top.indexOf("%")',
            //   oDragObj.style.top
            // );
            nTY = parseInt(50 * height / 100 + 0);
            nTX = parseInt(50 * width / 100 + 0);
          } else {
            nTY = parseInt(oDragObj.style.top + 0);
            nTX = parseInt(oDragObj.style.left + 0);
          }
          y = nn6 ? e.clientY : event.clientY;
          x = nn6 ? e.clientX : event.clientX;
          oDragObj.style.cursor = "move";
          document.onmousemove = moveMouse;
          return false;
        }
      }
      document.onmousemove = initDrag;
      // document.onmouseup = new Function("isdrag=false");
      document.onmouseup = function(e) {
        isdrag = false;
        document.onmousemove = null;
        document.onmouseup = null;
        var oDragHandle = nn6 ? e.target : event.srcElement;
        var topElement = "HTML";
        while (
          oDragHandle.tagName != topElement &&
          oDragHandle.className != "movableItem"
        ) {
          oDragHandle = nn6
            ? oDragHandle.parentNode
            : oDragHandle.parentElement;
        }
        if (oDragHandle.className == "movableItem") {
          oDragObj = oDragHandle;
          oDragObj.style.cursor = "Default";
        }
      };
      ev = event || window.event;

      // 取消事件冒泡行为
      // window.event ? (window.event.cancelBubble = true) : ev.stopPropagation();
    },

  },
  destroyed() {
    clearInterval(this.timer);
  },
// 使用组件的情况下 监听了图片
  watch: {
    equipment() {
      if (this.equipment.length != 0) {
        this.arrIcon = [];
        let finish = true;
        this.equipment.filter(item => {
          if (!item.iconImgUrl) {
            finish = false;
          }
          return true;
        });
        console.log("finishtest", finish);
        if (finish) {
          this.equipment.filter((item, index) => {
            if (index >= this.imgIndex) {
              console.log("iconImgUrl", this.equipment[index].iconImgUrl);
              this.getImgInfo(
                this.$baseUrl + item.iconImgUrl,
                this.iconMaxWidth,
                this.iconMaxHeight,
                "iconWidth",
                "iconHeight",
                true,
                "arrIcon"
              );
            }
            console.log("22filter", index);
            return true;
          });
        }
      }
    },
    imgUrl(val) {
      this.getImgInfo(
        val,
        this.bigMaxWidth,
        this.bigMaxHeight,
        "width",
        "height"
      );
      console.log("pic", val);
    }
  }

}

最后补充,上面代码里面写了  IE浏览器没有e.path 我也是查了一堆方法函数去替换然后还是在我的软件环境里面不起作用,就没有采用;上面的注释不够完整,很多打印可以自行删除。总体而言功能实现了即可。

上面代码我也是从一位老哥那参照修改,功能没他的复杂,这里非常感谢 附上他的链接

https://blog.csdn.net/weixin_43245095/article/details/107972629



版权声明:本文为qq_31452297原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。