JS实现放大镜案例

放大镜案例

实现效果如下图所示:
在这里插入图片描述

第一步:结构分析

结构分析
1-一个大盒子 div.box
2-一个放中等图片的盒子 div.middleBox
一张中等图片
一个遮罩层 div.shade
3-一个放小图片的盒子 div.smallBox
两张小图片
4-一个放大图的盒子div.bigBox

结构代码:

<div class="box">
    <div class="middleBox">
      <img src="../img/middle1.jpg" alt="">
      <div class="shade"></div>
    </div>
    <div class="smallBox">
      <img src="../img/small1.jpg" middleImg="../img/middle1.jpg" bigImg="../img/big1.jpg" class="active">
      <img src="../img/small2.jpg" middleImg="../img/middle2.jpg" bigImg="../img/big2.jpg">
    </div>
    <div class="bigBox"></div>
  </div>

样式:

  <style>
    *{margin: 0; padding: 0;}
    .box{
      width: 402px;
      position: relative;
      margin: 0 auto;
    }
    .middleBox{
      width: 400px;
      height: 400px;
      border: 1px solid #000;
    }
    .middleBox>img{
      width: 400px;
      height: 400px;
    }
    .middleBox>.shade{
      width: 200px;
      height: 200px;
      background-color: yellow;
      opacity: .5;
      position: absolute;
      top: 0px;
      left: 0px;
      cursor: move;
    }
    .smallBox{
      margin-top: 15px;
    }
    .smallBox>img{
      width: 50px;
      height: 50px;
      border: 1px solid #000;
      margin-left: 5px;
    }
    .smallBox>img.active{
      border: 3px solid red;
    }
    .bigBox{
      width: 400px;
      height: 400px;
      border: 1px solid #000;
      position: absolute;
      top: 0px;
      left: 105%;
      background-image: url("../img/big1.jpg");
      background-repeat: no-repeat;
      background-position: 0 0;
      background-size: 800px 800px;
      display: none;
    }
  </style>

效果分析:
1-点击小图片,添加被选中的样式,中图片和大图片切换
2-鼠标移入中图片,遮罩层显示;移出,遮罩层和大图片隐藏
3-鼠标在中盒子中移动,遮罩层跟随移动
4-遮罩层移动,大盒子图片跟随移动

代码实现:

// 创建放大镜Enlarge构造函数
function Enlarge(){
  // 获取要操作的元素,并放到实例对象的属性中
  this.box = document.querySelector('.box')
  this.middleBox = document.querySelector('.middleBox')
  this.middleImg = document.querySelector('.middleBox>img')
  this.shade = document.querySelector('.shade')
  this.bigBox = document.querySelector('.bigBox')
  this.smallImgs = document.querySelectorAll('.smallBox>img')
}
// 给原型添加一个bind方法,实现元素的事件绑定
Enlarge.prototype.bind = function(){
  // 给每一张小图片绑定点击事件
  for(let i = 0; i<this.smallImgs.length; i++){
    this.smallImgs[i].onclick = () => {
      // 1-实现小图样式切换
      this.tab(this.smallImgs[i])
    }
  }
  // 中图片中鼠标移入移出事件
  this.middleBox.onmouseenter =  ()=>{
    this.shade.style.display = 'block'
    this.bigBox.style.display = 'block'
    // 鼠标移动事件
    this.middleBox.onmousemove = ()=> {
      // 遮罩层跟随鼠标一起移动
      this.move()
    }
  }
  this.middleBox.onmouseleave = () => {
    this.shade.style.display = 'none'
    this.bigBox.style.display = 'none'
    this.middleBox.onmousemove = null
  }
}

// 给原型添加一个tab方法,实现切换小图样式和中大图片
Enlarge.prototype.tab = function(ele){
  for(let i=0; i<this.smallImgs.length; i++){
    this.smallImgs[i].className = ''
  }
  ele.className = 'active'
  // 切换中盒子和大盒子中的图片
  let bigImg = ele.getAttribute('bigImg')
  let middleImg = ele.getAttribute('middleImg')
  this.middleImg.setAttribute('src',middleImg)
  this.bigBox.style.backgroundImage = `url(${bigImg})`
}
// 给原型添加一个move方法 ,遮罩层跟随鼠标一起移动
Enlarge.prototype.move = function(e){
  e = e || window.event
  // 获取鼠标相对于页面左上角的位置
  let x = e.pageX
  let y = e.pageY
  // 获取遮罩层的一般宽高
  let shadeHalfWidth = this.shade.clientWidth/2
  let shadeHalfHeight = this.shade.clientHeight/2
  // 获取中图片盒子距离页面上方和左方的位置
  let boxLeft = this.box.offsetLeft
  let boxTop =this.box.offsetTop
  // 判断鼠标在盒子中移动的范围
  if(x<shadeHalfWidth+boxLeft){
    x = shadeHalfWidth+boxLeft
  }
  if(y<shadeHalfHeight+boxTop){
    y = shadeHalfHeight+boxTop
  }
  if(x>boxLeft+this.middleBox.clientWidth-shadeHalfWidth){
    x = boxLeft+this.middleBox.clientWidth-shadeHalfWidth
  }
  if(y>boxTop+this.middleBox.clientHeight-shadeHalfHeight){
    y = boxTop+this.middleBox.clientHeight-shadeHalfHeight
  }
  // 将计算好的坐标赋值给遮罩层
  this.shade.style.left = x - boxLeft - shadeHalfWidth + 'px'
  this.shade.style.top = y - boxTop - shadeHalfHeight + 'px'
  // 遮罩层移动,大图片跟随移动
  this.bigImgMove()
}

// 在原型中添加一个bigImgMove函数,实现大图片移动
Enlarge.prototype.bigImgMove = function(){
  // 获取遮罩层在中盒子中的位置
  let shadeX = parseInt(getStyle(this.shade,'left'))
  let shadeY = parseInt(getStyle(this.shade,'top'))
  let bigImgSize = getStyle(this.bigBox,'background-size')
  let bigImgWidth = parseInt(bigImgSize.split(' ')[0])
  let bigImgHeight = parseInt(bigImgSize.split(' ')[1])
  // 获取垂直和水平百分比
  let xPercent = shadeX / this.middleBox.clientWidth
  let yPercent = shadeY / this.middleBox.clientHeight
  // 根据百分比计算大和中背景图移动的距离
  let bigImgLet = bigImgWidth * xPercent
  let bigImgTop = bigImgHeight * yPercent
  // 位置赋值给大盒子
  this.bigBox.style.backgroundPosition = `-${bigImgLet}px -${bigImgTop}px`
}
// 实例化
let enlarge = new Enlarge()
enlarge.bind()

// 获取元素样式
function getStyle(ele,style){
  try{
    return window.getComputedStyle(ele)[style]
  }catch(error){
    return ele.currentStyle[style]
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值