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

原生JavaScript实现放大镜效果详解
本文详述如何使用原生JavaScript实现一个放大镜效果,包括分析放大镜结构、CSS样式设置和DOM操作。通过跟随鼠标移动,实现放大镜的显示与隐藏,以及放大图片的移动,确保不超出图片内部。同时提供了一个GitHub地址供读者参考学习。

原生js实现一个放大镜

学习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, 而右边我们移动的是bigImg, glass往左边移动(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'; 

总结

以上就是实现一个放大镜的全部内容

附上gitHub地址:欢迎来踩coder66y/js-practice: some interesting practices of js (github.com)

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值