放大镜效果

放大镜效果

在电商平台中,我们常常见到比如放大镜这样的效果,例如:

放大镜功能

这样的效果是怎么实现的呢,他主要由三部分组成:

  1. 原始图片
  2. 放大图片
  3. 遮罩层

首先研究遮罩层,当鼠标移入图片中,遮罩层的位置也随之改变思路如下:

  1. 我们可以先设定好一个遮罩层,给其指定宽高(为图片大小的一半),并设置定位 position,后期我们需要改变这个left以及top实现遮罩层的位置改变。

    <!-- 遮罩层 -->
    <div class="mask"></div>
    <!--这里使用的为 less-->   
    <style lang="less">
    .mask {
        // 设置宽高为大盒子的一般
        width: 50%;
        height: 50%;
        // 设置背景颜色
        background-color: rgba(0, 255, 0, 0.3);
        // 设置定位
        position: absolute;
        // 设置初始位置
        left: 0;
        top: 0;
        // 默认不显示,当鼠标移入时显示
        display: none;
      }
    // 当鼠标移入时显示
    .event:hover ~ .mask,
    .event:hover ~ .big {
       display: block;
    }
    </style>
    
  2. 当鼠标移入图片时会触发鼠标移动(mousemove)事件,并会传入一个 event 事件对象,其中包含的 offsetX,offsetY(相对于这个图片边界的X,Y值)就是我们需要的内容,使用 event.offsetWidth(offsetHeight) 可以获取当前元素的宽高。

  3. 获取mask节点,当鼠标移动时,改变 mask 的 left 和 top,注意:这里的 left 以及 top,应当是

    鼠标当前位置相对于图片边界坐标 - mask元素的宽高的一半,也就是:

    document.querySelector(".mask").addEventListener('mousemove',(event)=>{
       let left = event.offsetX - mask.offsetWidth / 2;
       let top = event.offsetY - mask.offsetHeight / 2;
       mask.style.left = left + 'px';
       mask.style.top = top + 'px';
    })
    

    基础功能实现,但是现在遮罩层可以超出边界,如下图:

出现问题

  1. 所以我们需要添加一些判断。如果两项相减小于0,就让这个宽高等于0;如果两项相减大于 mask 的宽高,就让这个值等于 mask 的宽高;

    document.querySelector(".mask").addEventListener('mousemove',(event)=>{
        let mask = document.querySelector(".mask");
        let left = event.offsetX - mask.offsetWidth / 2;
        let top = event.offsetY - mask.offsetHeight / 2;
        // 约束范围
        if (left <= 0) left = 0;
        if (left >= mask.offsetWidth) left = mask.offsetWidth;
        if (top <= 0) top = 0;
        if (top >= mask.offsetHeight) top = mask.offsetHeight;
        mask.style.left = left + 'px';
        mask.style.top = top + 'px';
    })
    
    

    实现功能如下:

遮罩层功能完成

实现完遮罩层的功能之后,我们要试着实现放大镜的功能了。

  1. 定义一个放大镜的盒子,命名为 big,放大镜的原理就是,将区域图片的宽高都放大一倍,就像是放大了一样。

    <div class="big">
        <img src="imgUrl" />
    </div>
    <style lang="less">
        .big {
            // 定义盒子的宽高,这里的宽高要和原始图片宽高一致
            width: 100%;
            height: 100%;
            // 开启定位,将放大镜与原始图片齐平
            position: absolute;
            top: 0;
            left: 100%;
            border: 1px solid #aaa;
            // 隐藏超出部分
            overflow: hidden;
            z-index: 1000;
            display: none;
            background: white;
    		// 设置放大镜中的图片
            img {
                // 设置图片宽度为.big的二倍
                width: 200%;
                max-width: 200%;
                // 设置图片高度为.big的二倍
                height: 200%;
                // 设置定位,通过更改定位left以及top进行放大的同步展示
                position: absolute;
                left: 0;
                top: 0;
            }
        }
    </style>
    
  2. 当鼠标在原始图片上移动时,改变.big中图片的 left 以及 top。代码与上方一致,这里一定要用-2,用2则方向相反。

    big.style.top = -2 * top + 'px';
    big.style.left = -2 * left + 'px';
    
  3. 至此,功能完成。

全部代码:

  <div class="spec-preview">
    <img src="imgUrl" />
    <div class="event"></div>
    <div class="big">
      <img ref="big" src="imgUrl" />
    </div>
    <!-- 遮罩层 -->
    <div class="mask"></div>
  </div>
</template>

<script>
   document.querySelector(".mask").addEventListener('mousemove',(event)=>{
      let mask = document.querySelector(".mask");
      let big = document.querySelector(".big img");
      let left = event.offsetX - mask.offsetWidth / 2;
      let top = event.offsetY - mask.offsetHeight / 2;
      // 约束范围
      if (left <= 0) left = 0;
      if (left >= mask.offsetWidth) left = mask.offsetWidth;
      if (top <= 0) top = 0;
      if (top >= mask.offsetHeight) top = mask.offsetHeight;
      mask.style.left = left + 'px';
      mask.style.top = top + 'px';
      big.style.top = -2 * top + 'px';
      big.style.left = -2 * left + 'px';
    };
</script>

<style lang="less">
  .event {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 998;
  }

  .mask {
    width: 50%;
    height: 50%;
    background-color: rgba(0, 255, 0, 0.3);
    position: absolute;
    left: 0;
    top: 0;
    display: none;
  }

  .big {
    width: 100%;
    height: 100%;
    position: absolute;
    top: -1px;
    left: 100%;
    border: 1px solid #aaa;
    overflow: hidden;
    z-index: 1000;
    display: none;
    background: white;

    img {
      width: 200%;
      max-width: 200%;
      height: 200%;
      position: absolute;
      left: 0;
      top: 0;
    }
  }

  .event:hover ~ .mask,
  .event:hover ~ .big {
    display: block;
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值