美文网首页
vue 实现图片放大镜

vue 实现图片放大镜

作者: 帅气的名称被占用 | 来源:发表于2019-04-23 15:31 被阅读0次

    新建imageBig.vue

    <style>
      #_magnifier_layer{position: absolute; z-index: 9999; background: #f9f9f9;}
      ._magnifier{position: relative;display: inline-block;}
      ._magnifier img{vertical-align: middle;}
      ._magnifier_zoom{position: absolute; top:0;left:0; z-index: 10;pointer-events:none;}
    </style>
    <template>
      <div class="_magnifier">
        <img :src="src" :width="width" :height="height" @mouseover="handOver"  @mousemove="handMove" @mouseout="handOut"/>
      </div>
    </template>
    
    <script>
      export default {
        name: 'app',
        props: {
          src: {
            type: String,
            required: true
          },
          bigsrc: {
            type: String,
            required: true
          },
          width:{
            type: String,
            default:'auto'
          },
          height:{
            type: String,
            default:'auto'
          },
          configs: {
            type: Object,
            default() {
              return {
                width:750,
                height:450,
                maskWidth:50,
                maskHeight:50,
                maskColor:'#fff',
                maskOpacity:0.5
              }
            }
          }
        },
        data() {
          return {
            imgObj:{},
            bigImg:{},
            mouseMask:{},
            imgLayer:{},
            imgRect:{},
          }
        },
        methods: {
          handMove(e) {
            let objX=e.pageX - this.imgRect.left;
            let objY=e.pageY - this.imgRect.top;
            let backgroundX=objX*(Math.ceil(this.bigImg.width/this.imgObj.offsetWidth)/1.5);
            let backgroundY=objY*(Math.ceil(this.bigImg.height/this.imgObj.offsetHeight)/1.5);
            //判断是否超出界限
            let _maskX=objX-this.mouseMask.offsetHeight/2;
            let _maskY=objY-this.mouseMask.offsetWidth/2;
            if(_maskY<=0){
              _maskY=0;
            }
            if(_maskY+this.mouseMask.offsetHeight>=this.imgRect.height){
              _maskY=this.imgRect.height-this.mouseMask.offsetHeight;
            }
            if(_maskX<=0){
              _maskX=0;
            }
            if(_maskX+this.mouseMask.offsetWidth>=this.imgRect.width){
              _maskX=this.imgRect.width-this.mouseMask.offsetWidth;
            }
            this.mouseMask.style.webkitTransform=`translate3d(${_maskX}px,${_maskY}px,0)`;
            //判断背景图是否小于预览框
            if(backgroundY+this.configs.height>=this.bigImg.height){
              backgroundY=this.bigImg.height-this.configs.height;
            }
            if(backgroundX+this.configs.width>=this.bigImg.width){
              backgroundX=this.bigImg.width-this.configs.width;
            }
            this.imgLayer.style.backgroundPositionX= `-${backgroundX}px `;
            this.imgLayer.style.backgroundPositionY= `-${backgroundY}px `;
          },
          handOut(e) {
            this.imgLayer.remove();
            this.mouseMask.remove();
          },
          handOver(e) {
            if (!document.getElementById('_magnifier_layer')) {
              //获取大图尺寸
              this.imgObj= this.$el.getElementsByTagName('img')[0];
              this.imgRect =this.imgObj.getBoundingClientRect();
              this.bigImg = new Image();
              this.bigImg.src = this.bigsrc;
              //创建鼠标选择区域
              this.mouseMask = document.createElement("div");
              this.mouseMask.className='_magnifier_zoom';
              this.mouseMask.style.background=this.configs.maskColor;
              this.mouseMask.style.height=this.configs.maskWidth+'px';
              this.mouseMask.style.width=this.configs.maskHeight+'px';
              this.mouseMask.style.opacity=this.configs.maskOpacity;
              this.imgObj.parentNode.appendChild(this.mouseMask);
              //创建预览框
              let imgLayer = document.createElement("div");
              this.imgLayer=imgLayer;
              let _layerHeight= this.configs.height;
              let _layerWidth= this.configs.width;
              imgLayer.id = '_magnifier_layer';
              imgLayer.style.width = _layerWidth + 'px';
              imgLayer.style.height = _layerHeight + 'px';
              imgLayer.style.left =this.imgRect.left+this.imgRect.width + 'px';
              imgLayer.style.top = this.imgRect.top+ 'px';
              imgLayer.style.backgroundImage = `url('${this.bigsrc}')`;
              imgLayer.style.backgroundRepeat = 'no-repeat';
              document.body.appendChild(imgLayer);
            }
          }
        }
      }
    </script>
    

    新建app.vue刚才新建的组件

      <div id="app">
        <div class="img-con">
          <img-zoom src="src/img/img-samll.png" bigsrc="src/img/img-big.jpg" ></img-zoom>
        </div>
        <div class="img-con2">
          <img-zoom src="src/img/img-samll.png" width="450" height="250" bigsrc="src/img/img-big.jpg" :configs="configs"></img-zoom>
        </div>
      </div>
    </template>
    
    <script>
      import imgZoom from './imgZoom.vue';
    export default {
      name: 'app',
      data () {
        return {
          configs: {
            width:650,
            height:350,
            maskWidth:100,
            maskHeight:100,
            maskColor:'red',
            maskOpacity:0.2
          }
        }
      },
      components:{
        imgZoom
      }
    }
    </script>
    
    <style lang="scss">
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 10px;
    }
    .img-con{border: 1px solid #ccc; text-align: center; padding:0;}
    .img-con2{border: 1px solid #bbb; text-align: center; float: left; margin-top: 20px;}
    </style>
    

    相关文章

      网友评论

          本文标题:vue 实现图片放大镜

          本文链接:https://www.haomeiwen.com/subject/xcwvgqtx.html