图片放大镜组件分析

网上图片放大镜组价开发示例代码很多,虽然方法大致相同,可是都没有很好的注释,由于我要做的页面用到了这个组件,我就把代码进行了梳理和分析,做了详尽的注释,并因情景做了相应的改动。

首先要明白一些基础的概念,例如offsetTop,offsetWidth之类的定义,直接贴图:


明白这些定义之后,就可以很好的分析下面的代码了,首先放大镜组件要四个小块组成:正常的小盒子,小盒子里的选中区域,大图片以及放大后的图片容器(大盒子):


图片地址是从应用此组件的父组件获得的,以下是对代码的梳理和注释:

结构:

<!--放大镜模块-->
<template>
  <div class="magnifier">
    <div class="img-box" @mousemove="move($event)"  @mouseout="out" ref="previewBox">
      <img :src="imgUrl"  height="520" width="520" :onerror="defaultImg">
      <div class="hover-box" ref="hoverBox"></div>
    </div>
    <div class="zoom-box" v-show="zoomVisiable" ref="zoomBox">
      <img :src="imgUrl"  ref="bigImg">
    </div>
  </div>

</template>

方法:

out () {
      this.zoomVisiable = false
    },
    move (ev) {
      this.init()
      const scrollY = document.documentElement.scrollTop || document.body.scrollTop // 垂直滚动条的位置
      let moveX = ev.clientX // 鼠标距离屏幕距离
      let moveY = ev.clientY
      let offsetLeft = this.oPreviewBox.offsetParent.offsetLeft // 小盒子距离页面左边的距离
      let offsetTop = this.oPreviewBox.offsetParent.offsetTop // 小盒子距离页面顶部的距离
      let left = moveX - offsetLeft - this.hoverWidth / 2 // 黄色区域距离小盒子左边的距离
      let top
      if (scrollY > 0) { // 如果向上滚动要加上滚动距离,moveY只是鼠标相对屏幕的坐标位置
        top = moveY - offsetTop + scrollY - this.hoverHeight / 2
      } else {
        top = moveY - offsetTop - this.hoverHeight / 2
      }
      let maxWidth = this.pWidth - this.hoverWidth // 小盒子宽-黄色区域宽
      let maxHeight = this.pHeight - this.hoverHeight // 小盒子高-黄色区域高


      left = left < 0 ? 0 : left > maxWidth ? maxWidth : left // 判断黄色区域是否超出小盒子左右,如果超出,左边left为0,右边为maxWidth
      top = top < 0 ? 0 : top > maxHeight ? maxHeight : top // 判断黄色区域是否超出小盒子上下,如果超出,上边top为0,下边为maxHeight
      let percentX = left / (maxWidth)
      let percentY = top / (maxHeight)


      this.oHoverBox.style.left = left + 'px' // 黄色区域在小盒子里的实际位置
      this.oHoverBox.style.top = top + 'px'
      this.oBigImg.style.left = percentX * (this.bWidth - this.imgWidth) + 'px'
      this.oBigImg.style.top = percentY * (this.bHeight - this.imgHeight) + 'px'
      this.$emit('move', ev)
      this.zoomVisiable = true
    },
    init () {
      this.oHoverBox = this.$refs.hoverBox // 小盒子中的黄色区域
      this.oPreviewBox = this.$refs.previewBox // 小盒子
      this.oBigImg = this.$refs.bigImg // 放大的图片
      this.imgBox = this.$refs.zoomBox // 大盒子


      this.hoverWidth = this.oHoverBox.offsetWidth // 黄色区域的宽高
      this.hoverHeight = this.oHoverBox.offsetHeight
      this.pWidth = this.oPreviewBox.offsetWidth // 小盒子宽高
      this.pHeight = this.oPreviewBox.offsetHeight


      this.imgWidth = this.oBigImg.offsetWidth // 大图片宽高
      this.imgHeight = this.oBigImg.offsetHeight
      this.bWidth = this.imgBox.offsetWidth // 大盒子宽高

      this.bHeight = this.imgBox.offsetHeight

样式:

.magnifier {
  .img-box {
    position: relative;
    width: 520;
    height: 522px;
    margin-bottom: 10px;
    border: 1px solid #E9E9E9;
    background-size: cover;
    background-image: ('/static/default.png');
    &:hover .hover-box {
      display: block;
    }
    .hover-box {
      position: absolute;
      display: none;
      left: 0;
      top: 0;
      width: 303px;
      height: 303px;
      border: 1px solid #545454;
      background:50% top no-repeat #fede4f;
      opacity:.5;
      cursor: move;
      user-select: none;
    }
  }
  .zoom-box {
    z-index: 999;
    width: 540px;
    height: 610px;
    overflow: hidden;
    position: absolute;
    left: 520px;
    border: 1px solid #e4e4e4;
    top: 0;
    img {
      width: 800px;
      position: absolute;
      top: 0;
      left: 0;
    }
  }
}

猜你喜欢

转载自blog.csdn.net/zhaoyizhu1990/article/details/80855889
今日推荐