记录一次原生js实现放大镜效果。

文章目录

  • 效果图
  • 设计思路
    • 基本架子
    • 蒙版
    • 放大效果图
  • 逻辑设计
    • 蒙版跟放大的图肯定要先隐藏
    • 鼠标移入图片显示蒙版
    • 鼠标移动蒙版跟着移动
  • 处理边界情况
  • 大图移动
  • 小优化
  • 终版
  • 博客

效果图

设计思路

基本架子

先弄一个容器放正常的图片,中间那个蒙版(稍微有点透明的白色正方形),肯定给绝对定位,动态调lefttop值,

所以子绝父相,父容器给相对定位。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.zoom-info {width: 400px;height: 400px;border: 1px solid pink;}.zoom-info .zoom img {width: 100%;height: 100%;position: relative;}</style>
</head><body><div class="zoom-info"><img src="./2.png" alt=""></div>
</body></html>

视图:

蒙版

在弄个正方形蒙版出来,这个正方形蒙版,就是说,你鼠标移动到这个图片里面时,正方形的蒙版的中心肯定是跟随你的鼠标移动的。就是你想放大的那个区域。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.zoom-info {width: 400px;height: 400px;border: 1px solid pink;}.zoom-info img {width: 100%;height: 100%;position: relative;}/* 新增 */.zoom-info .mask {width: 200px;height: 200px;background: rgba(255, 255, 255, 0.5);position: absolute;border: 1px solid #ddd;left: 0;top: 0;}</style>
</head><body><div class="zoom-info"><div class="zoom"><img src="./2.png" alt=""></div><!-- 新增 --><div class="mask"></div></div>
</body></html>

视图:

放大效果图

放大效果图跟原来的图片是一样的,有一个地方不同的是放大效果图的宽高相对于原图是大了一倍,然后父盒子还是跟左边图片一样的宽度,溢出隐藏这样图片放大效果就有了。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;}.zoom-info {width: 400px;height: 400px;border: 1px solid pink;}.zoom-info .zoom img {width: 100%;height: 100%;position: relative;}.zoom-info .mask {width: 200px;height: 200px;background: rgba(255, 255, 255, 0.5);position: absolute;border: 1px solid #ddd;left: 0;top: 0;}/* 新增 */.zoom-info .big-img {width: 400px;height: 400px;position: absolute;border: 1px solid #ddd;left: 420px;top: 0;overflow: hidden;}/* 新增 */.zoom-info .big-img img {width: 800px;height: 800px;}</style>
</head><body><div class="zoom-info"><div class="zoom"><img src="./2.png" alt=""></div><div class="mask"></div><!-- 新增 --><div class="big-img"><img src="./2.png" alt=""></div></div>
</body></html>

视图:

逻辑设计

蒙版跟放大的图肯定要先隐藏

这里给相关的类名加一个display:none属性就行了

鼠标移入图片显示蒙版

给图片加一个mousemove事件,鼠标移入调整display: block就行了

上脚本代码

  <script>window.addEventListener('load', () => {// 原始图片 .zoom divconst originDom = document.querySelector('.zoom')console.log(originDom)// 正方形蒙版const maskDom = document.querySelector('.mask')// 大图const bigImgDom = document.querySelector('.big-img')originDom.addEventListener('mousemove', () => {maskDom.style.display = 'block'bigImgDom.style.display = 'block'})})</script>

亲测没问题,不贴视图了

鼠标移动蒙版跟着移动

鼠标移动的时候,正方形蒙版肯定也要跟着移动,因为蒙版的中心位置肯定是鼠标,上这部分的处理逻辑,这个地方要说明一个东西,就是鼠标移动的时候,肯定要动态改变蒙版的lefttop值,怎么改呢?看示意图

注意这个地方不理解好,你后面的东西做不了,这个地方理解了你就没啥大问题了对于放大镜。

写到这里,有一件非常重要的事情,这时候你要回头给一个地方添加css属性,就是给蒙版加一个pointer-events: none;,为什么呢,请参考一下这篇文章,当前你也可以选择不加,后面看看会出什么样的bug再解决也不迟。

  <script>window.addEventListener('load', () => {// 原始图片 .zoom divconst originDom = document.querySelector('.zoom')console.log(originDom)// 正方形蒙版const maskDom = document.querySelector('.mask')// 大图const bigImgDom = document.querySelector('.big-img')originDom.addEventListener('mousemove', (e) => {maskDom.style.display = 'block'bigImgDom.style.display = 'block'// 获取鼠标到图片左侧,上侧的位移const { offsetX, offsetY } = e// 获取蒙版的宽const maskWidth = maskDom.offsetWidth// 获取蒙版的高const maskHeight = maskDom.offsetHeight// 计算left的值let left = offsetX - maskWidth / 2// 计算top的值let top = offsetY - maskHeight / 2// 赋值maskDom.style.left = `${left}px`maskDom.style.top = `${top}px`})})</script>

这样鼠标移动的时候蒙版也会跟着移动了

处理边界情况

这个时候会有这么一个问题,就是蒙版会超出img容器,示例

=

所以要处理边界情况:

        // 处理左边和顶部溢出if (left < 0) {left = 0}if (top < 0) {top = 0}// 处理右边和下边溢出,left + 蒙版的宽不能大于整个图片容器宽if ((left + maskWidth) >= originDom.offsetWidth) {left = originDom.offsetWidth - maskWidth}// top + 蒙版的高不能大于整个图片容器高if ((top + maskHeight) >= originDom.offsetHeight) {top = originDom.offsetHeight - maskHeight}

大图移动

这里注意一点,你想想看,鼠标向左移动,实际上大图要跟着向右移动,为啥呢?因为大图向右移动,我们才能看到大图左边的东西呀,哈哈哈,

这个地方要搞清楚,不然会一脸懵逼,而且还有一点要注意的是你要移动的是图片,而不是大图外层的div,因为外层div是溢出隐藏的,注意,注意,注意记得回头给大图img标签一个绝对定位的属性,不然你的left,top是不生效的。还有一个要注意的地方就是大图移动的距离你可以根据比例来计算。上代码。

        // 比例为大图在父div容器可以移动的距离除以蒙版在小图可以移动的距离const ratio = (bigImg.offsetWidth - bigImgDom.offsetWidth) / (originDom.offsetWidth - maskWidth)const bigImgLeft = left * ratioconst bigImgTop = top * ratio// 大图移动bigImg.style.left = `-${bigImgLeft}px`bigImg.style.top = `-${bigImgTop}px`

小优化

代码写到这里,放大镜基本上已经完成了,我们来做一些小优化,鼠标移除原始图片的时候,肯定要,把正方形蒙版和大图隐藏,所以上代码

    // 监听鼠标移除事件
originDom.addEventListener('mouseleave', () => {maskDom.style.display = 'none'bigImgDom.style.display = 'none'})

然后我们给鼠标移入原始图片加一个小手手的样式,更好看一点

    .zoom-info {width: 400px;height: 400px;border: 1px solid pink;cursor: pointer;}

终版

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>原生js实现放大镜效果</title><style>* {margin: 0;padding: 0;}.zoom-info {width: 400px;height: 400px;border: 1px solid pink;position: relative;}.zoom-info .zoom {width: 400px;height: 400px;cursor: pointer;position: relative;}.zoom-info .zoom img {width: 100%;height: 100%;position: relative;vertical-align: top;}.zoom-info .mask {width: 200px;height: 200px;background: rgba(255, 255, 255, 0.5);position: absolute;left: 0;top: 0;display: none;pointer-events: none;}.zoom-info .big-img {width: 400px;height: 400px;position: absolute;border: 1px solid #ddd;left: 420px;top: 0;overflow: hidden;display: none;}.zoom-info .big-img img {width: 800px;height: 800px;position: absolute;}</style>
</head><body><div class="zoom-info"><div class="zoom"><img src="./2.png" alt=""></div><div class="mask"></div><div class="big-img"><img src="./2.png" alt="" class="big"></div></div><script>let originDom, maskDom, bigImg = nullwindow.addEventListener('load', () => {// 原始图片 .zoom divoriginDom = document.querySelector('.zoom')// 正方形蒙版maskDom = document.querySelector('.mask')// 大图divbigImgDom = document.querySelector('.big-img')// 大图图片img标签bigImg = document.querySelector('.big')handleMouseMove()handleMouseLeave()})// 处理鼠标移动function handleMouseMove() {originDom.addEventListener('mousemove', (e) => {maskDom.style.display = 'block'bigImgDom.style.display = 'block'// 获取鼠标到图片左侧,上侧的位移const {offsetX,offsetY} = e// 获取蒙版的宽const maskWidth = maskDom.offsetWidth// 获取蒙版的高const maskHeight = maskDom.offsetHeight// 计算left的值let left = offsetX - maskWidth / 2// 计算top的值let top = offsetY - maskHeight / 2// 处理左边和顶部溢出if (left < 0) {left = 0}if (top < 0) {top = 0}// 处理右边和下边溢出,left + 蒙版的宽不能大于整个图片容器宽if ((left + maskWidth) >= originDom.offsetWidth) {left = originDom.offsetWidth - maskWidth}// top + 蒙版的高不能大于整个图片容器高if ((top + maskHeight) >= originDom.offsetHeight) {top = originDom.offsetHeight - maskHeight}// 赋值maskDom.style.left = `${left}px`maskDom.style.top = `${top}px`// 比例为大图在父div容器可以移动的距离除以蒙版在小图可以移动的距离const ratio = (bigImg.offsetWidth - bigImgDom.offsetWidth) / (originDom.offsetWidth - maskWidth)const bigImgLeft = left * ratioconst bigImgTop = top * ratio// 大图移动bigImg.style.left = `-${bigImgLeft}px`bigImg.style.top = `-${bigImgTop}px`})}// 处理鼠标离开function handleMouseLeave() {originDom.addEventListener('mouseleave', () => {maskDom.style.display = 'none'bigImgDom.style.display = 'none'// 解绑事件originDom.onmousemove = nulloriginDom.obmouseleave = null})}</script>
</body></html>

注意注意注意直接复制粘贴该html代码是运行不了的,因为图片你是没有的哈,记得自己弄2张图片!!!。

博客

欢迎访问我的博客www.smartxy.cc

原生js实现放大镜效果相关推荐

  1. 原生JS实现分页效果1.0

    不太完整,写的太急,等等加上完整注释,写起来还是有些难度的,写的有点水,后面再改进改进. <!DOCTYPE html> <html lang="en"> ...

  2. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  3. html制作满天星,怎样使用原生js做出满天星效果

    这次给大家带来怎样使用原生js做出满天星效果,使用原生js做出满天星效果的注意事项有哪些,下面就是实战案例,一起来看一下. 代码如下://图片自己加入改变路径 html{height: 100%;} ...

  4. 原生js实现如下效果: 一个按钮,点击它会弹出对话框,但5秒内再点击不会再弹出对话框。5秒后恢复正常。

    原生js实现如下效果: 一个按钮,点击它会弹出对话框,但5秒内再点击不会再弹出对话框.5秒后恢复正常. 第一种方式: 使用函数节流的方式(就是设置一个变量,来一个判断语句,判断这个变量的值.为真或假执 ...

  5. 原生js添加动画效果

    原生js添加动画效果 html 这个图片是使用阿里图标需要下载 <div class="content"><div class="contAnimati ...

  6. 原生JS实现分页效果

    做开发久了,会越来越依赖框架,毕竟利用框架可以快速的完成工作任务,如常见的分页效果,只需要与后端配合,由后端返回总页数和当前第几页这两个参数传给一些框架的分页功能,就可以轻松的实现分页效果,那如果在不 ...

  7. 原生js漂浮广告效果

    原生js漂浮广告效果 静态页面代码 <body><div id="box"><img src="1.jpg" alt=" ...

  8. 原生js制作动画效果

    理论基础:需要获取元素的任意css属性值 getComputedStyle(element,null),支持谷歌,火狐 element.currentStyle,支持ie8 //获取任意css属性值( ...

  9. html萤火虫特效代码,原生JS实现萤火虫效果

    本文实例为大家分享了JS实现萤火虫效果的具体代码,供大家参考,具体内容如下 上代码之前,先看一下效果: CSS部分(此处用元素模拟萤火虫,背景可自行设置): .box{width: 4px;heigh ...

最新文章

  1. rdlc报表显示条码 .
  2. Gengine规则引擎
  3. Java 面试 80% 的人都会踩这些坑,你知道几种?
  4. 学习ASP.NET之前,先了解它
  5. 从办公桌可以看透一个人
  6. python or 和and的优先级_python中not、and和or的优先级与详细用法介绍
  7. 这样的科幻不该被埋没,吐血推荐!
  8. [web开发] Vue+Spring Boot 上海大学预约系统开发记录
  9. STM32F401标准固件库配置
  10. 台式机连接蓝牙音响没声音 以及 声音延迟 问题解决
  11. 一个小把戏算法,获取大乐透,并且计算出最佳的结果(Qt C++ 和Android共用)
  12. 华为nova7星耀版和华为nova7普通版 的区别 哪个好
  13. 龙芯Fedora21平台制作docker镜像,并且解决vi乱码问题
  14. python turtle 库绘制简单魔法阵
  15. PLC通信协议【三菱Q系列】MC协议
  16. 改进的Salp Swarm优化算法(ISSA)(Matlab代码实现)
  17. 花开富贵--国兰的基本介绍
  18. 免费MP4转换GIF工具开源
  19. 王码星空,一场令人感伤的发布会
  20. python多分支语句实例_Python分支语句与循环语句应用实例分析

热门文章

  1. 【人工智能笔记】第三十节:注意力原理分析,及tensorflow 2.0 实现
  2. 全网爆火五款高性能旗舰蓝牙耳机推荐,平价高音质蓝牙耳机
  3. Java网络通信实验小记四:Swing聊天软件
  4. 图像的峰值信噪比(peak signal to noise ratio, PSNR)
  5. .c和.h文件的区别
  6. 多模态机器学习简述(Guide to Multimodal Machine Learning)
  7. 阿里云,华为云哪个更好?
  8. GStreamer基础教程10——GStreamer工具
  9. linux英伟达显卡驱动390下载,nvidia英伟达驱动|NVIDIA英伟达显卡驱动程序更新下载(32/64位) v384.90 Linux版 - 飞极下载站...
  10. 【Linux】ssh连接远程服务器