当前位置 : 主页 > 网络编程 > JavaScript >

原生js实现一个放大镜效果超详细

来源:互联网 收集:自由互联 发布时间:2023-01-19
目录 前言: 一、放大镜效果 二、实现步骤 1. 首先分析放大镜结构 2. 整体样式---css部分 3. JS操作dom实现放大镜 总结 前言: 学习js之初,写过js放大镜,但是当时模模糊糊,似懂非懂,
目录
  • 前言:
  • 一、放大镜效果
  • 二、实现步骤
    • 1. 首先分析放大镜结构
    • 2. 整体样式---css部分
    • 3. JS操作dom实现放大镜
  • 总结

    前言:

    学习js之初,写过js放大镜,但是当时模模糊糊,似懂非懂,最近重温js内容,决定重写了一下这个放大镜效果,希望可以让初学者对js-DOM的练习更好上手

    一、放大镜效果

    二、实现步骤

    1. 首先分析放大镜结构

    • 左边图片:img---原图片
    • 左边图片里面的类似于放大镜的遮罩层:glass---用于选择需要放大的部分
    • 右边放大的图片:bigImg ---用于展示放大效果

    html代码如下:

      <div class="box">
        <div class="glassWrapper">
          <img src="./assets/green.jpg" class="img"/>
          <div class="glass" id="glass"></div>
        </div>
        <div class="bigWrapper">
          <img src="./assets/green.jpg" class="bigImg"/>
        </div>
      </div>

    2. 整体样式---css部分

    整体居中: 左右两张图片居中垂直使用flex布局,网上很多,这里不多说布局问题

    右边放大效果的关键样式: 底部有一张大图片,有一个固定的框展示放大的部分,超过这个展示款的部分就遮住,从而出现一种被放大的效果,使用:overflow: hidden; 

     图片移动的关键: 移动的图片使用:绝对定位(注意子绝父相)

    css代码:

    .glassTitle {
      color: #89cff0;
      text-align: center;
    }
    
    .box {
      width: 80vw;
      min-width: 800px;
      height: 80vh;
      min-height: 600px;
      line-height: 80vh;
      display: flex;
      align-items: center;
      justify-content: space-around;
      background-color: #f2f3f4;
      margin: 10px auto;
      border-radius: 10px;
      box-shadow: 0px 0px 10px 1px #5d8aa8;
    }
    
    .glassWrapper{
      line-height: 0;
      position: relative;
    }
    
    .img {
      display: block;
      width: 250px;
      height: auto;
    }
    
    .glass {
      position: absolute;
      width: 80px;
      height: 80px;
      background: #89cff0;
      opacity: .5;
      display: none;
    }
    
    .bigWrapper {
      position: relative;
      width: 500px;
      height: 500px;
      background-color: #fff;
      border: 1px dashed #89cff0;
      border-radius: 10px;
      overflow: hidden;
    }
    
    .bigImg {
      width: 2500px;
      display: none;
      position: absolute;
    }

    3. JS操作dom实现放大镜

    现在样式和结构都准备好了,就差来操作DOM了

    1. 实现glass跟随鼠标移动

    效果是只要鼠标进入img中,就出现glass,出去就消失,所以给img添加鼠标监听事件mouseover,原本imgdisplay:none, 后变成display:block,离开img的鼠标监听事件是mouseout,

    const glassWrapper = document.querySelector('.glassWrapper'); // 放大镜的盒子
      glassWrapper.addEventListener('mouseover', () => {
        glass.style.display = 'block';
        bigImg.style.display = 'block';
      });
      
      glassWrapper.addEventListener('mouseout', () => {
        glass.style.display = 'none';
        bigImg.style.display = 'none';
      })

    2. 实现glass跟随鼠标移动,并且鼠标位于glass中央

    如图: 

    • e.pageX是鼠标相对于文档(document)的水平坐标, e.pageY是鼠标相对文档的垂直坐标
    • glassWrapper.offsetWidthglassWrapper元素的水平偏移位置,glassWrapper.offsetTopglassWrapper元素的垂直偏移位置,
    • e.pageX - glassWrapper.offsetLeft可以得到鼠标相对于glassWrapper的偏移量x
    • x - glass.offsetWidth / 2:x减去glass宽度的一半就可以得到glass相对于glassWrapper的偏移量,即可得到绝对定位的left,同理Top也可以得到
    • 以下代码即可实现glass跟随鼠标移动

    为什么因为glass是相对于glassWrapper而移动的?因为css里面的子绝父相

      box.addEventListener('mousemove', (e) => {
        // 该操作让glassWrapper的左上角变成坐标原点, 因为glass是先相对于glassWrapper而移动的
        const x = e.pageX - glassWrapper.offsetLeft;
        const y = e.pageY - glassWrapper.offsetTop;
        // 让鼠标在glass的中间位置
        let width = x - glass.offsetWidth / 2;
        let height = y - glass.offsetHeight / 2;
    
        // 改变放大镜的位置
        glass.style.left = width + 'px';
        glass.style.top = height + 'px';

    3. glass不超出img内部

    如图绝对定位的left, 也就是width的最小是0,最大是glassWrapper.offsetWidth - glass.offsetWidth

      box.addEventListener('mousemove', (e) => {
        // 该操作让glassWrapper的左上角变成坐标原点, 因为glass是先相对于glassWrapper而移动的
        const x = e.pageX - glassWrapper.offsetLeft;
        const y = e.pageY - glassWrapper.offsetTop;
        // 让鼠标在glass的中间位置
        let width = x - glass.offsetWidth / 2;
        let height = y - glass.offsetHeight / 2;
        // 让glass不超出img内部
      + if (width <= 0) {
      +   width = 0;
      + } else if (width >= glassWrapper.offsetWidth - glass.offsetWidth) {
      +   width = glassWrapper.offsetWidth - glass.offsetWidth;
      + }
      + if (height <= 0) {
      +   height = 0;
      + } else if (height >= glassWrapper.offsetHeight - glass.offsetHeight) {
      +   height = glassWrapper.offsetHeight - glass.offsetHeight;
      + }
    
        // 改变放大镜的位置
        glass.style.left = width + 'px';
        glass.style.top = height + 'px';
     })

    4.重点:放大的图片的移动--较难理解

    • 首先确定放大比例并更改大图片的大小

    放大比例是由glassbigWrapper之间的比例来决定的,所以首先先计算大图片应该有多大,bigImg.style.width = img.offsetWidth * bigWrapper.offsetWidth / glass.offsetWidth + 'px';并且更改大图片的大小;

    • 移动大图片left的正负

    小图片img和大图片bigImgleft都是相对其父元素的,不同的是:左边我们移动的是glass, 而右边我们移动的是bigImgglass往左边移动(left为正),相当于视口相对于图片往左边移动,反过来,图片就是相对于视口往右边移(bigImg的left为负),所以bigImgleftglassleft是符号是相反的

    • left的比例

    bigImg移动的距离是glass移动的距离之间的比例由:大图片和小图片之间的比例(或者glass和glassWrapper之间的比例)来决定

        // 改变大图片的位置
        bigImg.style.width = img.offsetWidth * bigWrapper.offsetWidth / glass.offsetWidth + 'px';
        bigImg.style.left = - width * bigImg.offsetWidth / img.offsetWidth + 'px';
        bigImg.style.top = - height * bigImg.offsetHeight / img.offsetHeight + 'px';

    总结

    到此这篇关于原生js实现一个放大镜效果超详细的文章就介绍到这了,更多相关js放大镜效果内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    网友评论