vue項目js實現圖片放大鏡功能

效果圖:
 
我寫的是vue的組件形式,方便複用,圖片的寬高,縮放的比例能夠本身定義
magnifier.vue
<template>
  <div class="magnify">
  <!-- 左邊產品圖片區域 -->
    <div class="left_contaner">
      <div class="middle_img" @mouseover="boxMouseOver" @mouseleave="boxMouseLeave">
      <!-- 產品圖片 -->
        <img :src="middleImg" alt="">
        <!-- 陰影盒子 -->
        <div class="shade" @mouseover="shadeMouseOver" @mousemove="shadeMouseMove" ref="shade" v-show="isShade"></div>
      </div>
      <!-- 縮略圖容器 -->
      <div class="carousel">
      <!-- 左箭頭 -->
        <div class="left_arrow arrow" @click="leftArrowClick"></div>
        <!-- 縮略圖展現盒子 -->
        <div class="show_box">
          <ul class="picture_container" ref="middlePicture">
            <li class="picture_item" @mouseover="tabPicture(item)" v-for="(item, index) in pictureList" :key="index">
              <img :src="item.url" class="small_img" alt="">
            </li>
          </ul>
        </div>
        <!-- 向右箭頭 -->
        <div class="right_arrow arrow" @click="rightArrowClick"></div>
      </div>
    </div>
    <!-- 右邊放大區域 -->
    <div class="right_contanier" v-show="isBig">
      <img :src="middleImg" ref="bigImg" class="big_img" alt="">
    </div>
  </div>
</template>

<script>
import $ from 'jquery'
export default {
  props: {
    middleImgWidth: {
      default: 350,
      type: Number
    }, // 產品圖片寬
    middleImgHeight: {
      default: 400,
      type: Number
    }, // 產品圖片高
    thumbnailHeight: {
      default: 100,
      type: Number
    }, // 縮略圖容器高度
    imgList: Array, // 圖片數據
    zoom: {
      default: 2, // 縮略比例,放大比例
      type: Number
    }
  },
  data() {
    return {
      pictureList: [
        {url: 'http://mp.ofweek.com/Upload/News/Img/member645/201711/17170046839337.jpg'},
        {url: 'http://image.buy.ccb.com/merchant/201703/904919627/1522929521661_4.jpg'},
        {url: 'http://image5.suning.cn/uimg/b2c/newcatentries/0070130691-000000000826244625_5_800x800.jpg'},
        {url: 'http://img12.360buyimg.com/n5/s450x450_jfs/t9952/98/2269407420/279171/6137fe2f/59f28b2bN6959e086.jpg'},
        {url: 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'},
        {url: 'http://d.ifengimg.com/w600/p0.ifengimg.com/pmop/2017/1213/A4037864F6728F006B67AAEC51EC8A485F320FD2_size93_w1024_h734.jpeg'}
      ],
      middleImg: '', // 中圖圖片地址
      bigImg: '', // 大圖圖片地址
      isShade: false, // 控制陰影顯示與否
      isBig: false, // 控制放大圖顯示與否
      initX: 0, // 初始clientX值
      initY: 0, // 初始clientY值
      leftX: 0, // 初始定位left
      topY: 0, // 初始定位top
      middleLeft: 0, // 當前放置小圖盒子的定位left值,
      itemWidth: 80, // 縮略圖每張的寬度
    }
  },
  created() {
    if (this.imgList && this.imgList.length) {
      this.pictureList = this.imgList
    }
    this.middleImg = this.pictureList[0].url
    // 計算縮略圖的寬度,默認是顯示4張圖片,兩邊箭頭的寬度和爲50
    this.itemWidth = (this.middleImgWidth-50) / 4
  },
  mounted() {
    this.$nextTick(() => {
      // 容器的高
      const imgWidth = this.middleImgHeight + this.thumbnailHeight + 20
      // 設置容器寬高
      $('.magnify').css({
        width: this.middleImgWidth,
        height: imgWidth
      })
      // 設置產品圖寬高
      $('.middle_img').css({
        width: this.middleImgWidth,
        height: this.middleImgHeight
      })
      // 設置移動陰影圖寬高
      $('.middle_img .shade').css({
        width: this.middleImgWidth/this.zoom,
        height: this.middleImgHeight/this.zoom
      })
      // 設置縮略圖容器高
      $('.carousel').css({
        height: this.thumbnailHeight
      })
      // 設置每一個縮略圖寬
      $('.picture_item').css({
        width: this.itemWidth
      })
      // 設置放大後圖片容器的寬高,left
      $('.right_contanier').css({
        left: this.middleImgWidth,
        width: imgWidth,
        height: imgWidth
      })
      // 設置放大圖片的寬高(圖片的放大倍數)
      $('.right_contanier .big_img').css({
        width: imgWidth * this.zoom,
        height: imgWidth * this.zoom
      })
    })
  },
  methods: {
    // 產品圖片鼠標移入事件,顯示陰影,顯示大圖
    boxMouseOver (e) {
      console.log(9999, e)
      e.preventDefault();
      e.stopPropagation();
      this.isShade = true
      this.isBig = true
      // 計算陰影的位置
      let x = e.offsetX - $('.shade').width()/2
      let y = e.offsetY - $('.shade').height()/2
      let maxLeft = $('.middle_img').width() - $('.shade').width() 
      let maxTop = $('.middle_img').height() - $('.shade').height()
      x = x <= 0 ? 0 : x
      x = x >= maxLeft ? maxLeft : x
      y = y <= 0 ? 0 : y
      y = y >= maxTop ? maxTop : y
     $('.shade').css({
         left: x,
         top: y
        })
    },
    // 鼠標在陰影移動
    shadeMouseMove (e) {
      e.preventDefault();
      e.stopPropagation();
     //用頁面x - 父盒子的offsetLeft - 父盒子的左邊框寬度
    var x = this.getEventPage(e).pageX - $('.middle_img')[0].offsetParent.offsetLeft - $('.middle_img')[0].offsetParent.clientLeft;
    //用頁面y - 父盒子的offsetTop - 父盒子的上邊框寬度
    var y = this.getEventPage(e).pageY - $('.middle_img')[0].offsetParent.offsetTop - $('.middle_img')[0].offsetParent.clientTop;

     //讓陰影的座標居中
    x -= $('.shade').width() / 2;
    y -= $('.shade').height() / 2;

     // 移動邊界限制
    let maxLeft = $('.middle_img').width() - $('.shade').width()
    let maxTop = $('.middle_img').height() - $('.shade').height()
    x = x <= 0 ? 0 : x
    x = x >= maxLeft ? maxLeft : x
    y = y <= 0 ? 0 : y
    y = y >= maxTop ? maxTop : y
     // 從新賦值當前的定位值
    $('.shade').css({
      left: x,
      top: y
    })
      // 計算出實時的大圖的定位,首先計算出比例
      // 比例爲x:大圖寬度/小圖寬度 y: 大圖高度/小圖高度,將小圖的定位乘以比例就是大圖的定位
      const xRate = $('.big_img').width() / $('.middle_img').width()
      const yRate = $('.big_img').height() / $('.middle_img').height()
      $('.big_img').css({
        left: -x*xRate,
        top: -y*yRate
      })
      // console.log(e, x, y, xRate, yRate, 66677)
    },
    // 鼠標移入陰影,去除自定義事件
    shadeMouseOver (e) {
      e.preventDefault();
      e.stopPropagation();
      // console.log(88888, e)
    },
    // 圖片移出隱藏陰影和大圖
    boxMouseLeave (e) {
      this.isShade = false
      this.isBig = false
    },
    // 切換圖片
    tabPicture (item) {
      this.middleImg = item.url
    },
    // 點擊左邊箭頭
    leftArrowClick () {
      if (this.middleLeft < 0) {
        // 每次向右平移一個圖片盒子的寬度
        this.middleLeft += this.itemWidth
        $('.picture_container').animate({
          left: this.middleLeft
        }, 500)
      }
    },
    // 點擊右邊箭頭
    rightArrowClick () {
      // 每次向左平移一個盒子的寬度,最多移動的寬度爲(圖片數組長度-4)*每張縮略圖的寬度
      if (this.middleLeft > -this.itemWidth*(this.pictureList.length-4)) {
        this.middleLeft -= this.itemWidth
        $('.picture_container').animate({
          left: this.middleLeft
        }, 500)
      }
      console.log(this.middleLeft)
    }
  }
}
</script>

<style scoped>
.magnify {
  position: relative;
}
.left_contaner {
  width: 100%;
  height: 100%;
}
.left_contaner .middle_img {
  border: 1px solid #ccc;
  box-sizing: border-box;
  position: relative;
}
.left_contaner .shade {
  background-color: rgba(    135,206,235, .5);
  position: absolute;
  top: 0;
  left: 0;
 cursor: move;
}
.left_contaner .middle_img img { width: 100%; height: 100%; } .left_contaner .carousel { width: 100%; margin-top: 20px; display: -webkit-flex; } .left_contaner .carousel .show_box { flex: 1; overflow: hidden; position: relative; } .left_contaner .carousel .arrow { flex-basis: 25px; cursor: pointer; } .left_contaner .carousel .left_arrow { background: url('http://www.jq22.com/demo/jQuery-fdj201705051102/images/btn_prev.png') no-repeat; background-position: center center; } .left_contaner .carousel .right_arrow { background: url('http://www.jq22.com/demo/jQuery-fdj201705051102/images/btn_next.png') no-repeat; background-position: center right; } .left_contaner .carousel .picture_container { width: 200%; height: 100%; position: absolute; overflow: hidden; top: 0; left: 0; } .left_contaner .picture_container .picture_item { height: 100%; float: left; padding: 5px; box-sizing: border-box; } .left_contaner .picture_container .picture_item:hover { border: 2px solid #f2019f; } .left_contaner .picture_container .picture_item img { width: 100%; height: 100%; } .right_contanier { overflow: hidden; position: absolute; top: 0; border: 1px solid #ccc; } .right_contanier .big_img { position: absolute; top: 0px; left: 0px; } </style>

 

父組件引用
 
<template>
 <div id="app">
  <img alt="Vue logo" src="./assets/logo.png">
  <!-- 圖片放大鏡,須要自定義圖片的寬高在這裏傳入,組件有設置默認的寬高,不傳也能夠 -->
  <magnifier></magnifier>
 </div>
</template>
<script>
// 引入放大鏡組件
import Magnifier from './components/magnifier.vue'
import $ from 'jquery'
export default {
name: 'app',
components: {
  // 註冊
 Magnifier
 }
}
 
 git-hup地址:  https://github.com/shengbid/my-element  這個文件是平時練習的項目,裏面還有一些我寫的其餘博客的源碼,有須要能夠下載看看
相關文章
相關標籤/搜索