精华内容
下载资源
问答
  • vue实现放大镜效果

    2020-10-14 18:27:52
    主要为大家详细介绍了vue实现放大镜效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • Vue实现商品放大镜效果

    千次阅读 多人点赞 2021-09-25 11:24:45
    在这个鼎盛的电商时代各种直播带货或者自主逛宝购物,我们对商品的认知和了解进一步查看详情,发现我们的商品可以放大观看,于是心血来潮运用前端技术Vue框架,写了一个类似放大镜的功能 二、 实现思路: 对原图的显示...

    一、前言:

    在这个鼎盛的电商时代各种直播带货或者自主逛宝购物,我们对商品的认知和了解进一步查看详情,发现我们的商品可以放大观看,于是心血来潮运用前端技术Vue框架,写了一个类似放大镜的功能

    二、 实现思路:

    对原图的显示空间(left) 可以将显示原图可 img 换成canvas,来对图片行进行保护 ,
    跟随鼠标移动时显示放大的指示区(鼠标层罩top) ,显示层罩区域选中放大的显示空间(right)

    三、效果展示

    在这里插入图片描述

    四、具体实现逻辑代码

    template (记得改图片路径)

    <template>
      <div>
        <div class="left">
          <img class="leftImg" src="../../src/assets/curry.jpg" alt="" />
          <!-- 鼠标层罩 -->
          <div v-show="topShow" class="top" :style="topStyle"></div>
          <!-- 最顶层覆盖了整个原图空间的透明层罩 -->
          <div
            class="maskTop"
            @mouseenter="enterHandler"
            @mousemove="moveHandler"
            @mouseout="outHandler"
          ></div>
        </div>
        <div v-show="rShow" class="right">
          <img
            :style="r_img"
            class="rightImg"
            src="../../src/assets/curry.jpg"
            alt=""
          />
        </div>
      </div>
    </template>
    

    style css

    <style scoped>
    /* 放大的图片,通过定位将左上角定位到(0,0) */
    .rightImg {
      display: inline-block;
      width: 800px;
      height: 800px;
      position: absolute;
      top: 0;
      left: 0;
    } /* 右边的区域图片放大空间 */
    .right {
      margin-left: 412px;
      width: 400px;
      height: 400px;
      border: 1px solid red;
      position: relative;
      overflow: hidden;
    } /* 一个最高层层罩 */
    .maskTop {
      width: 400px;
      height: 400px;
      position: absolute;
      z-index: 1;
      top: 0;
      left: 0;
    } /* 层罩,通过定位将左上角定位到(0,0) */
    .top {
      width: 200px;
      height: 200px;
      background-color: lightcoral;
      opacity: 0.4;
      position: absolute;
      top: 0;
      left: 0;
    } /* 原图的显示 */
    .leftImg {
      width: 400px;
      height: 400px;
      display: inline-block;
    } /* 原图的容器 */
    .left {
      width: 400px;
      height: 400px;
      border: 1px solid teal;
      float: left;
      position: relative;
    }
    </style>
    

    script 核心js

    <script>
    export default {
      data() {
        return {
          topStyle: { transform: "" },
          r_img: {},
          topShow: false,
          rShow: false,
        };
      },
      methods: {
        // 鼠标进入原图空间函数
        enterHandler() {
          // 层罩及放大空间的显示
          this.topShow = true;
          this.rShow = true;
        },
        // 鼠标移动函数
        moveHandler(event) {
          // 鼠标的坐标位置
          let x = event.offsetX;
          let y = event.offsetY;
          // 层罩的左上角坐标位置,并对其进行限制:无法超出原图区域左上角
          let topX = x - 100 < 0 ? 0 : x - 100;
          let topY = y - 100 < 0 ? 0 : y - 100;
          // 对层罩位置再一次限制,保证层罩只能在原图区域空间内
          if (topX > 200) {
            topX = 200;
          }
          if (topY > 200) {
            topY = 200;
          }
          // 通过 transform 进行移动控制
          this.topStyle.transform = `translate(${topX}px,${topY}px)`;
          this.r_img.transform = `translate(-${2 * topX}px,-${2 * topY}px)`;
        },
        // 鼠标移出函数
        outHandler() {
          // 控制层罩与放大空间的隐藏
          this.topShow = false;
          this.rShow = false;
        },
      },
    };
    </script>
    
    

    五、总结思考

    原本我是将三个鼠标事件添加在原图容器 left 上的,结果不断出现问题
    1、在我加了一个覆盖了鼠标区域的透明层罩 maskTop 才让这个放大镜能完整的实现,若是不加这个 maskTop 层罩,在我鼠 标进入原图区域空间时鼠标层罩不会跟着鼠标的移动而移动,更是会在鼠标移动时进行高频率的“颤动”,右边的放大区域空间 也没有顺畅的跟着移动变化
    2、若是没有添加 maskTop 层罩,在我鼠标移入原图区域空间时, mousemove 鼠标移动事件只执行了一次,似乎是因为鼠 标层罩阻挡了
    3、在之前有试过动态地确定鼠标层罩的初始位置,将其放在了mouseenter事件当中,结果 mouseenter 事件执行了异常多次,就像是变成了 mousemove 事件
    有看过其他的放大镜案例,但是他们都不需要加 masktop 这个最顶层的覆盖层罩,期望能有路过的大佬帮忙解惑

    展开全文
  • 使用vue实现商品放大镜效果

    千次阅读 2019-11-07 11:17:56
    <!-- 放大图片 --> v-show="elemenImgShow" ref="thum...
    // 此代码依赖于vue 通过使用组件的方式引用此代码 需要传入的数据均写有注释
    //这次主要优化了放大图片的位移比例 使放大图片的位移更加精确 更符合用户习惯 添加了缩略图片超出处理样式 
    
    // 优化之后的代码
    <template>
      <div class="magnifier">
        <div class="outer-box">
          <!-- 放大图片 -->
          <div class="magnifier-box"
               v-show="elemenImgShow"
               ref="thumbnailBox">
            <div class="inner-box"
                 ref="maginiferInnerbox">
              <img ref="thumbnailImg"
                   :src="magnifierImgArr.magnifier[imgIndex].src"
                   alt="">
            </div>
          </div>
          <!-- 展示的图片 -->
          <div class="img-show"
               ref="imgShowBox">
            <div class="magnifier-img"
                 v-show="elemenImgShow"
                 ref="magnifierImg"></div>
            <img :src="magnifierImgArr.showImg[imgIndex].src"
                 alt="">
            <div class="transparent"
                 @mousemove="magnifiermove($event)"
                 @mouseleave="elemenImgShow = false"></div>
    
          </div>
          <!-- 缩略图 -->
          <div class="img-thumbnail flexbox between">
            <div class="icon"
                 @click="nextPic"
                 v-if="iconShow">&lt;</div>
            <div class="rel-box"
                 rel="ulOuterBox">
              <ul class=""
                  ref="ulList">
                <li v-for="(item, index) in thumbnailForArr"
                    :key="index"
                    @mouseenter="thumbnailEnter(index)"
                    :class="{'active':imgIndex===index}">
                  <img :src="item.src"
                       alt=""
                       srcset="">
                </li>
              </ul>
            </div>
            <div class="icon"
                 v-if="iconShow"
                 @click="previous">&gt;</div>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: ['magnifierImgArr', 'goodsBoxWidth', 'reload'],
      /*
        magnifierImgArr
        传入的图片对象集合 数据格式 :
          magnifierImgArr: {
              //缩略图图片数组
             thumbnail: [{src: ''}],
              //要放大的图片数组
             showImg: [{src:''}]
              //放大的图片数组
             magnifier: [{src:''}]
           },
          // 其中缩略图图片数组可以不传 如果不传将自动使用 要放大的图片数组 的数据
          // goodsBoxWidth
          // 设置放大的图片盒子的宽度 尽量沾满商品图片的右边部分
           // reload 如果传入的数据发生变化自动将图片索引下标变为0
      */
      watch: {
        reload () {
          if (this.reload === 1) {
            this.imgIndex = 0
          }
        }
      },
      data () {
        return {
          // magnifierImgArr: {
          //   // 缩略图图片数组
          //   thumbnail: [
          //     { src: require('../assets/img/letter-img/22628333-1_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-2_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-3_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-4_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-5_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-1_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-2_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-3_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-4_x_2.jpg') },
          //     { src: require('../assets/img/letter-img/22628333-5_x_2.jpg') }
          //   ],
          //   // 要放大的图片数组
          //   showImg: [{ src: require('../assets/img/center/22628333-1_w_2.jpg') },
          //     { src: require('../assets/img/center/22628333-2_w_2.jpg') },
          //     { src: require('../assets/img/center/22628333-3_w_2.jpg') },
          //     { src: require('../assets/img/center/22628333-4_w_2.jpg') },
          //     { src: require('../assets/img/center/22628333-5_w_2.jpg') }],
          //   // 放大的图片数组
          //   magnifier: [
          //     { src: require('../assets/img/big/22628333-1_u_2.jpg') },
          //     { src: require('../assets/img/big/22628333-2_u_2.jpg') },
          //     { src: require('../assets/img/big/22628333-3_u_2.jpg') },
          //     { src: require('../assets/img/big/22628333-4_u_2.jpg') },
          //     { src: require('../assets/img/big/22628333-5_u_2.jpg') }
          //   ]
          // },
          imgIndex: 0,
          elemenImgShow: false,
          leftData: 0
        }
      },
      mounted () {
    
      },
      computed: {
        thumbnailForArr () {
          if (this.magnifierImgArr.thumbnail && this.magnifierImgArr.thumbnail.length) {
            return this.magnifierImgArr.thumbnail
          } else {
            return this.magnifierImgArr.showImg
          }
        },
        // 是否显示左右操作按钮
        iconShow () {
          if (this.thumbnailForArr.length > 5) {
            return true
          } else {
            return false
          }
        }
      },
      methods: {
        // 缩略图鼠标移入事件
        thumbnailEnter (i) {
          this.imgIndex = i
        },
        initData () {
          // 将放大盒子向右移动
          let outerBoxWidth = parseInt(this.$refs.imgShowBox.offsetWidth)
          // 放大镜盒子
          let thumbnailBox = this.$refs.thumbnailBox
          thumbnailBox.style.left = (outerBoxWidth + 15) + 'px'
          // 设置放大盒子的宽度
          if (this.goodsBoxWidth && this.goodsBoxWidth > 500) {
            thumbnailBox.style.width = this.goodsBoxWidth - outerBoxWidth - 75 + 'px'
          } else {
            thumbnailBox.width = 500 + 'px'
          }
        },
        magnifiermove (e) {
          // 有鼠标事件才加载大图片的位移 以解决在数据未加载之前就赋值了错误的位移
          this.initData()
          // 鼠标移入展示图片
          this.elemenImgShow = true
          // 鼠标下移动的半透明方块
          let magnifierEle = this.$refs.magnifierImg
          // 待放大的图片盒子宽高
          let outerBoxHeight = parseInt(this.$refs.imgShowBox.offsetHeight)
          let outerBoxWidth = parseInt(this.$refs.imgShowBox.offsetWidth)
          //  半透明方块的宽高
          let magnifierHeight = parseInt(magnifierEle.offsetHeight)
          let magnifierWidth = parseInt(magnifierEle.offsetWidth)
          // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          // 刚开始赋值left的初始值时就要减去放大镜图片宽度的一般 保证移动距离大于宽度一半之后才开始移动图片 top同理
          let left = e.offsetX - (magnifierWidth / 2)
          let top = e.offsetY - (magnifierHeight / 2)
          // 左边临界点
          left = left < 0 ? 0 : left
          //  右边临界点 透明方块可以移动的距离只有盛放商品展示图片盒子的宽度减去半透明盒子的宽度 如果移动的距离大于这个宽度 就将可移动距离设置为最大宽度 否则为鼠标移动的距离 top值同理
          left = left > outerBoxWidth - magnifierWidth ? outerBoxWidth - magnifierWidth : left
          magnifierEle.style.left = left + 'px'
          // 上面临界点
          top = top < 0 ? 0 : top
          // 下面临界点
          top = top > outerBoxHeight - magnifierHeight ? outerBoxHeight - magnifierHeight : top
          magnifierEle.style.top = top + 'px'
          // 放大的图片位移通过使用margin改变图片的位置 使用比例换算出移动的距离
          // 获取到需要放大的图片元素
          let thumbnailImgEle = this.$refs.thumbnailImg
          let maginiferInnerboxEle = this.$refs.maginiferInnerbox
          // 用大图片的宽高减去盛放大图片盒子的宽高就是可以移动的最大距离
          let maxLeft = thumbnailImgEle.offsetWidth - maginiferInnerboxEle.offsetWidth
          let maxTop = thumbnailImgEle.offsetHeight - maginiferInnerboxEle.offsetHeight
          // 换算出小图片对大图片的比例
          // 使用大图片可移动的距离除以放大镜可以移动的距离 即小图对大图的移动比例
          // 放大镜可移动的距离就是小图片盒子宽高减去放大镜盒子的宽高
          let leftScale = parseFloat((maxLeft / (outerBoxWidth - magnifierWidth)).toFixed(2))
          let topScale = parseFloat((maxTop / (outerBoxHeight - magnifierHeight)).toFixed(2))
          // 通过动态改变大图片的margin值实现图片移动
          thumbnailImgEle.style.marginLeft = '-' + (leftScale * left) + 'px'
          thumbnailImgEle.style.marginTop = '-' + (topScale * top) + 'px'
        },
        // 缩略图列表箭头的点击事件
        // 下一个
        nextPic () {
          this.positionDistance('next')
        },
        // 上一个
        previous () {
          this.positionDistance('prv')
        },
        positionDistance (nextOrPre) {
          let ulListEle = this.$refs.ulList
          let ulListEleWidth = ulListEle.offsetWidth
          // 设置单次移动的距离
          let num = ulListEleWidth / 4
          let distance = 0
          if (nextOrPre === 'next') {
            // 设置可以移动的最大距离
            let maxData = (this.thumbnailForArr.length * num) - ulListEleWidth
            distance = this.leftData >= maxData ? maxData : this.leftData + num
          } else {
            distance = this.leftData > num ? this.leftData - num : 0
          }
          ulListEle.style.left = '-' + distance + 'px'
          this.leftData = distance
        }
      }
    }
    </script>
    <style lang="less" scoped>
    .magnifier {
      min-width: 270px;
      padding: 10px;
      box-sizing: border-box;
      .outer-box {
        position: relative;
        width: 100%;
        height: 100%;
        .img-show {
          border: 1px solid #ccc;
          width: 100%;
          height: calc(100% - 80px);
          position: relative;
          .magnifier-img {
            width: 200px;
            height: 200px;
            background: rgba(160, 203, 236, 0.5);
            position: absolute;
            top: 0;
            left: 0;
            z-index: 10;
          }
          .transparent {
            cursor: move;
            width: 100%;
            height: 100%;
            background: none;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 20;
          }
          img {
            max-height: 100%;
            max-width: 100%;
          }
        }
        .img-thumbnail {
          width: 100%;
          margin-top: 10px;
          height: 54px;
          .icon {
            width: 35px;
            height: 35px;
            line-height: 25px;
            font-size: 14px;
            text-align: center;
            cursor: pointer;
            padding: 5px;
            box-sizing: border-box;
            background-color: #f5f5f5;
            // 禁止浏览器选中文字
            moz-user-select: -moz-none;
            -moz-user-select: none;
            -o-user-select: none;
            -khtml-user-select: none;
            -webkit-user-select: none;
            -ms-user-select: none;
            user-select: none;
            &:hover {
              background-color: #007acc;
              color: #fff;
            }
          }
          .rel-box {
            width: calc(100% - 60px);
            height: 100%;
            position: relative;
            overflow: auto;
            // 隐藏滚动条
            &::-webkit-scrollbar {
              display: none;
            }
            ul {
              position: absolute;
              left: 0;
              z-index: 100;
              top: 0;
              width: 100%;
              white-space: nowrap;
              li {
                width: calc(100% / 4);
                display: inline-block;
                height: 50px;
                border: 2px solid transparent;
                vertical-align: middle;
                box-sizing: border-box;
                &.active {
                  border-color: #f00;
                }
                text-align: center;
                img {
                  width: calc(100%);
                  height: calc(100%);
                }
              }
            }
          }
        }
        .magnifier-box {
          position: absolute;
          left: 50px;
          top: -5px;
          width: 500px;
          height: 330px;
          padding: 20px;
          z-index: 10;
          background-color: #fff;
          .inner-box {
            overflow: hidden;
            width: 100%;
            height: 100%;
            background-color: #fff;
          }
        }
      }
    }
    </style>
    
    
    
    // 未优化代码
    <template>
      <div class="magnifier">
        <div class="outer-box">
          <!-- 放大图片 -->
          <div class="magnifier-box"
               v-show="elemenImgShow"
               ref="thumbnailBox">
            <div class="inner-box">
              <img ref="thumbnailImg"
                   :src="magnifierImgArr.magnifier[imgIndex].src"
                   alt="">
            </div>
          </div>
          <!-- 展示的图片 -->
          <div class="img-show"
               ref="imgShowBox">
            <div class="magnifier-img"
                 v-show="elemenImgShow"
                 ref="magnifierImg"></div>
            <img :src="magnifierImgArr.showImg[imgIndex].src"
                 alt="">
            <div class="transparent"
                 @mousemove="magnifiermove($event)"
                 @mouseleave="elemenImgShow = false"></div>
          </div>
          <!-- 缩略图 -->
          <div class="img-thumbnail flexbox j-start">
            <li v-for="(item, index) in thumbnailForArr"
                :key="index"
                @mouseenter="thumbnailEnter(index)"
                :class="{'active':imgIndex===index}">
              <img :src="item.src"
                   alt=""
                   srcset="">
            </li>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: ['magnifierImgArr', 'goodsBoxWidth'],
      /*
        magnifierImgArr
        传入的图片对象集合 数据格式 :
          magnifierImgArr: {
              //缩略图图片数组
             thumbnail: [{src: ''}],
              //要放大的图片数组
             showImg: [{src:''}]
              //放大的图片数组
             magnifier: [{src:''}]
           },
          // 其中缩略图图片数组可以不传 如果不传将自动使用 要放大的图片数组 的数据
          // goodsBoxWidth
          // 设置放大的图片盒子的宽度 尽量沾满商品图片的右边部分
      */
      data () {
        return {
          // magnifierImgArr: {
          //   // 缩略图图片数组
          //   thumbnail: [{src: require('../assets/img/letter-img/22628333-1_x_2.jpg')},
          //     {src: require('../assets/img/letter-img/22628333-2_x_2.jpg')},
          //     {src: require('../assets/img/letter-img/22628333-3_x_2.jpg')},
          //     {src: require('../assets/img/letter-img/22628333-4_x_2.jpg')},
          //     {src: require('../assets/img/letter-img/22628333-5_x_2.jpg')}],
          //   // 要放大的图片数组
          //   showImg: [{src: require('../assets/img/center/22628333-1_w_2.jpg')},
          //     {src: require('../assets/img/center/22628333-2_w_2.jpg')},
          //     {src: require('../assets/img/center/22628333-3_w_2.jpg')},
          //     {src: require('../assets/img/center/22628333-4_w_2.jpg')},
          //     {src: require('../assets/img/center/22628333-5_w_2.jpg')}],
          //   // 放大的图片数组
          //   magnifier: [{src: require('../assets/img/big/22628333-1_u_2.jpg')},
          //     {src: require('../assets/img/big/22628333-2_u_2.jpg')},
          //     {src: require('../assets/img/big/22628333-3_u_2.jpg')},
          //     {src: require('../assets/img/big/22628333-4_u_2.jpg')},
          //     {src: require('../assets/img/big/22628333-5_u_2.jpg')} ]
          // },
          imgIndex: 0,
          elemenImgShow: false
        }
      },
      mounted () {
    
      },
      computed: {
        thumbnailForArr () {
          if (this.magnifierImgArr.thumbnail && this.magnifierImgArr.thumbnail.length) {
            return this.magnifierImgArr.thumbnail
          } else {
            return this.magnifierImgArr.showImg
          }
        }
      },
      methods: {
        // 缩略图鼠标移入事件
        thumbnailEnter (i) {
          this.imgIndex = i
        },
        initData () {
          // 将放大盒子向右移动
          let outerBoxWidth = parseInt(this.$refs.imgShowBox.offsetWidth)
          // 放大镜盒子
          let thumbnailBox = this.$refs.thumbnailBox
          thumbnailBox.style.left = (outerBoxWidth + 15) + 'px'
          // 设置放大盒子的宽度
          if (this.goodsBoxWidth && this.goodsBoxWidth > 500) {
            thumbnailBox.style.width = this.goodsBoxWidth - outerBoxWidth - 75 + 'px'
          } else {
            thumbnailBox.width = 500
          }
        },
        magnifiermove (e) {
          // 有鼠标事件才加载大图片的位移 以解决在数据未加载之前就赋值了错误的位移
          this.initData()
          // 鼠标移入展示图片
          this.elemenImgShow = true
          // 鼠标下移动的半透明方块
          let magnifierEle = this.$refs.magnifierImg
          // 待放大的图片盒子宽高
          let outerBoxHeight = parseInt(this.$refs.imgShowBox.offsetHeight)
          let outerBoxWidth = parseInt(this.$refs.imgShowBox.offsetWidth)
          //  半透明方块的宽高
          let magnifierHeight = parseInt(magnifierEle.offsetHeight)
          let magnifierWidth = parseInt(magnifierEle.offsetWidth)
          // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          // 刚开始赋值left的初始值时就要减去放大镜图片宽度的一般 保证移动距离大于宽度一半之后才开始移动图片 top同理
          let left = e.offsetX - (magnifierWidth / 2)
          let top = e.offsetY - (magnifierHeight / 2)
          // 左边临界点
          left = left < 0 ? 0 : left
          //  右边临界点 透明方块可以移动的距离只有盛放商品展示图片盒子的宽度减去半透明盒子的宽度 如果移动的距离大于这个宽度 就将可移动距离设置为最大宽度 否则为鼠标移动的距离 top值同理
          left = left > outerBoxWidth - magnifierWidth ? outerBoxWidth - magnifierWidth : left
          magnifierEle.style.left = left + 'px'
          // 上面临界点
          top = top < 0 ? 0 : top
          // 下面临界点
          top = top > outerBoxHeight - magnifierHeight ? outerBoxHeight - magnifierHeight : top
          magnifierEle.style.top = top + 'px'
          // 放大的图片位移通过使用margin改变图片的位置 使用比例换算出移动的距离
          // 获取到需要放大的图片元素
          let thumbnailImgEle = this.$refs.thumbnailImg
          // 换算出小图片对大图片的比例
          let leftScale = parseFloat((thumbnailImgEle.offsetWidth / (magnifierWidth / 2.5)).toFixed(2))
          let topScale = parseFloat((thumbnailImgEle.offsetHeight / ((magnifierHeight / 2.5))).toFixed(2))
          thumbnailImgEle.style.marginLeft = '-' + (leftScale * left) + 'px'
          thumbnailImgEle.style.marginTop = '-' + (topScale * top) + 'px'
        }
      }
    }
    </script>
    <style lang="less" scoped>
    .magnifier {
      width: 100%;
      height: 100%;
      padding: 10px;
      box-sizing: border-box;
      .outer-box {
        position: relative;
        width: 100%;
        height: 100%;
        .img-show {
          border: 1px solid #ccc;
          width: 100%;
          height: calc(100% - 80px);
          position: relative;
          .magnifier-img {
            width: 200px;
            height: 200px;
            background: rgba(160, 203, 236, 0.5);
            position: absolute;
            top: 0;
            left: 0;
            z-index: 10;
          }
          .transparent {
            cursor: move;
            width: 100%;
            height: 100%;
            background: none;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 20;
          }
          img {
            max-height: 100%;
            max-width: 100%;
          }
        }
        .img-thumbnail {
          margin-top: 10px;
          height: 54px;
          overflow: auto;
          li {
            width: 50px;
            height: 50px;
            border: 2px solid transparent;
            vertical-align: middle;
            &.active {
              border-color: #f00;
            }
            text-align: center;
            img {
              max-height: 100%;
              max-width: 100%;
            }
          }
        }
        .magnifier-box {
          position: absolute;
          left: 50px;
          top: -5px;
          width: 500px;
          height: 330px;
          padding: 20px;
          z-index: 10;
          background-color: #fff;
          .inner-box {
            overflow: hidden;
            width: 100%;
            height: 100%;
            background-color: #fff;
          }
        }
      }
    }
    </style>
    

     

     

    展开全文
  • vue项目中实现放大镜效果

    千次阅读 2020-03-04 22:32:00
    vue项目中可以用插件达到商城那个放大镜效果,当然也可以自己写方法,但想到快速的实现此功能就可以直接使用插件。 下载安装插件:npm i PicZoom --save 在要使用的地方引入:import PicZoom from “vue-piczoom...

    在vue项目中可以用插件达到商城那个放大镜效果,当然也可以自己写方法,但想到快速的实现此功能就可以直接使用插件。

    • 下载安装插件:npm i PicZoom --save
    • 在要使用的地方引入:import PicZoom from “vue-piczoom”; components: {
      PicZoom
      },
     <div class="showimg">
     		//要放大的图片,最好用盒子装起来
             <pic-zoom :url="imgurl" :scale="3"></pic-zoom>
           </div>
           <ul>
           //可供选择的小图片
             <li v-for="(item,index) in imgList" :key="index" @click="changeImage(index)">
               <img :src="item">
             </li>
           </ul> 
           <script>
            changeImage(index) {
         	console.log(index);
       	  this.imgurl = this.imgList[index];
       }       
        </script>
           ```
           
    
    展开全文
  • Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Webshell] @="URL:Webshell Protocol Handler" "URL Protocol"="" [HKEY_CLASSES_ROOT\Webshell\DefaultIcon] @="C:\\WINDOWS\\system32\\Magnify.exe" ...
  • Vue 实现图片放大镜效果

    千次阅读 2018-11-14 02:53:28
    Vue 实现图片放大镜效果 主要思路:展示一张图片,一个以该图片或大图为背景的div,背景图的宽高是 放大倍数乘原图的宽高 在内部放大时:以鼠标为中心点 取 放大倍数分之1 放大镜长度/2 的正方形的作为放大图像,...

    Vue 实现图片放大镜的效果

    主要思路:展示一张图片,一个以该图片或大图为背景的div,背景图的宽高是 放大倍数乘原图的宽高 在内部放大时:以鼠标为中心点放大倍数分之1 放大镜长度/2 的正方形的作为放大图像,以该正方形的左上角为起始点(top,left),相对于背景图的位置为(top放大倍数,left放大倍数),然后移动背景位置即可 在外部放大时:需要一个大小为放大镜宽高放大倍数的div来展示图像,起始点坐标是放大镜左上角的位置,然后放大即可

    源码
    <template>
     <div class="pic-img">
        <div class="img-container" @mousemove="!moveEvent && mouseMove($event)" @mouseleave="!leaveEvent && mouseLeave($event)">
          <img ref="img" @load="imgLoaded" :src="url" style="width:100%"></img>
          <div v-if="!hideZoom && imgLoadedFlag" :class="['img-selector',{'circle':type === 'circle'}]" :style="[imgSelectorSize,imgSelectorPosition,!outShow && imgSelectorBg ,!outShow && imgBgPosition]"> </div>
          <div v-if="outShow" v-show="!hideOutShow" class="img-out-show" :style="[imgOutShowSize,imgSelectorBg,imgBgPosition]"></div>
        </div>
      </div>
    </template>
    复制代码
    export default {
      name: 'vue-photo-zoom-pro',
      data() {
        return {
          selector: {
            width: 166,
            halfWidth: 83,
            top: 0,
            left: 0,
            bgTop: 0,
            bgLeft: 0,
            rightBound: 0,
            bottomBound: 0,
            absoluteLeft: 0,
            absoluteTop: 0
          },
          imgInfo: {},
          hideOutShow: true,
          imgLoadedFlag: false,
          screenWidth: document.body.clientWidth,
          timer: null
        };
      },
      props: {
        url: String,
        highUrl: String,
        type: {
          type: String,
          default: 'square',
          validator: function(value) {
            return ['circle', 'square'].indexOf(value) !== -1;
          }
        },
        scale: {
          type: Number,
          default: 3
        },
        moveEvent: {
          type: [Object, MouseEvent],
          default: null
        },
        leaveEvent: {
          type: [Object, MouseEvent],
          default: null
        },
        hideZoom: {
          type: Boolean,
          default: false
        },
        outShow: {
          type: Boolean,
          default: false
        }
      },
      watch: {
        moveEvent(e) {
          this.mouseMove(e);
        },
        leaveEvent(e) {
          this.mouseLeave(e);
        },
        url() {
          this.imgLoadedFlag = false;
        },
        screenWidth(val) {
          if (!this.timer) {
            this.screenWidth = val;
            this.timer = setTimeout(() => {
              this.imgLoaded();
              clearTimeout(this.timer);
              this.timer = null;
            }, 400);
          }
        }
      },
      computed: {
        imgSelectorPosition() {
          let { top, left } = this.selector;
          return {
            top: `${top}px`,
            left: `${left}px`
          };
        },
        imgSelectorSize() {
          let width = this.selector.width;
          return {
            width: `${width}px`,
            height: `${width}px`
          };
        },
        imgOutShowSize() {
          let {
            scale,
            selector: { width }
          } = this;
          return {
            width: `${width * scale}px`,
            height: `${width * scale}px`
          };
        },
        imgSelectorBg() {
          let {
            scale,
            url,
            highUrl,
            imgInfo: { height, width }
          } = this;
          return {
            backgroundImage: `url(${highUrl || url})`,
            backgroundSize: `${width * scale}px ${height * scale}px`
          };
        },
        imgBgPosition() {
          let { bgLeft, bgTop } = this.selector;
          return {
            backgroundPosition: `${bgLeft}px ${bgTop}px`
          };
        }
      },
      methods: {
        imgLoaded() {
          let imgInfo = this.$refs['img'].getBoundingClientRect();
          if (JSON.stringify(this.imgInfo) == JSON.stringify(imgInfo)) {  // 位置不变不更新
            return;
          }
          this.imgLoadedFlag = true;
          let { width, height, left, top } = (this.imgInfo = imgInfo);
          let selector = this.selector;
          let { width: selectorWidth, halfWidth: selectorHalfWidth } = selector;
          let { scrollLeft, scrollTop } = document.documentElement;
          selector.rightBound = width - selectorWidth;
          selector.bottomBound = height - selectorWidth;
          selector.absoluteLeft = left + selectorHalfWidth + scrollLeft;
          selector.absoluteTop = top + selectorHalfWidth + scrollTop;
        },
        reset() {
          Object.assign(this.selector, {
            top: 0,
            left: 0,
            bgLeft: 0,
            bgTop: 0
          });
        },
        mouseMove(e) {
          if (!this.hideZoom && this.imgLoadedFlag) {
            this.imgLoaded();   //防止img位置变化
            let { pageX, pageY } = e;
            let { scale, selector } = this;
            let {
              halfWidth,
              absoluteLeft,
              absoluteTop,
              rightBound,
              bottomBound
            } = selector;
            let x = pageX - absoluteLeft; // 选择器的x坐标 相对于图片
            let y = pageY - absoluteTop; // 选择器的y坐标
            if (this.outShow) {
              halfWidth = 0;
              this.hideOutShow = false;
            }
            selector.top = y > 0 ? (y < bottomBound ? y : bottomBound) : 0;
            selector.left = x > 0 ? (x < rightBound ? x : rightBound) : 0;
            selector.bgLeft = halfWidth - (halfWidth + x) * scale; // 选择器图片的坐标位置
            selector.bgTop = halfWidth - (halfWidth + y) * scale;
          }
        },
        mouseLeave() {
          if (this.outShow) {
            this.hideOutShow = true;
          }
        }
      }
    };
    复制代码
    .img-container {
      position: relative;
    }
    
    .img-selector {
      background-color: rgba(0, 0, 0, 0.6);
      position: absolute;
      background-repeat: no-repeat;
      cursor: crosshair;
      border: 1px solid rgba(0, 0, 0, 0.1);
    }
    
    .img-selector.circle {
      border-radius: 50%;
    }
    
    .img-out-show {
      position: absolute;
      top: 0;
      right: 0;
      background-repeat: no-repeat;
      transform: translate(100%, 0);
      border: 1px solid rgba(0, 0, 0, 0.1);
    }
    复制代码

    实现功能

    • 两种放大方式,内部放大以及外部放大
    • url hightUrl scale等属性动态变化

    展示

    demo

    github

    github.com/xbup/vue-ph…

    转载于:https://juejin.im/post/5beb8dd4f265da615e0504e7

    展开全文
  • 今天我们就自己动手封装一个放大镜效果的全局组件,一起来看下吧~ 一、封装的意义 从技术角度 通过vue插件方式封装为全局组件,整个项目其他位置也可以使用,且使用方便 模块化开发思想,一个模块实现一个功能 ...
  • PC端逛淘宝点进商品详情,鼠标挪到图片上右侧可见鼠标所到处细节放大,现在来掰扯掰扯↓↓↓↓↓↓ 效果图: 步骤解析: 1、创建一个大盒子,里面放左右两个大小相同的盒子 2、左边放入图片、鼠标遮罩层和图片遮罩...
  • 实现类淘宝放大镜效果 前端小白一枚,最近在进行 vue 方面的学习,逛淘宝闲来无事想试试做个放大镜,结果虽然做出来了,但其中有一些问题让我无法解决,四处搜索也没有找到满意的答案,很是心烦,希望能有大佬帮忙...
  • Vue 实现图片放大镜

    千次阅读 2020-05-12 13:54:34
    最近有项目需要用到对图片进行局部放大,类似淘宝商品页的放大镜效果,经过一番研究功能可用: HTML部分 <template> <div> <div class="choose" ref="choose"> <div class="content" ref...
  • 我之前有篇文章js实现图片放大镜效果:https://blog.csdn.net/yehaocheng520/article/details/115278622?spm=1001.2014.3001.5501 当时是用js实现的效果,因此现在要把代码嫁接到vue创建的项目中。 html部分代码: &...
  • Vue3.0 手写放大镜效果

    千次阅读 多人点赞 2021-07-23 10:07:18
    需要实现效果是: 固定放大两倍,鼠标进入到左侧图片区域的时候,遮罩层显示,离开时,遮罩层隐藏。 css中的cursor https://www.runoob.com/cssref/pr-class-cursor.html 鼠标跟随效果如何实现: (子绝父相)绝对...
  • 前端实现放大镜效果

    2021-06-29 18:08:32
    前端实现放大镜效果用到的技术注意事项效果展示代码实现 用到的技术 html + css + javascript + vue2.x + less 注意事项 代码中两处图片路径需要按照自己的情况修改,复制可用,根据放大镜大小需要适当修改计算...
  • const smallImgMouseMove = (e) => { e = e || window.event let x = e.clientX - 50 let y = e.clientY - 50 if (x >= 200) { x = 200; } if (x <...}

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 353
精华内容 141
关键字:

vue实现放大镜效果

vue 订阅