当前位置: 首页 > news >正文

Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

1、HTML 页面结构

2、CSS 元素样式

3、JavaScript动态控制

(1)获取元素

(2)控制大图和遮罩层的显隐性

(3)遮罩层跟随鼠标移动

(4)控制遮罩层移动范围

(5)显示放大图


一、需求描述

前端实现放大镜效果;

  • 鼠标移入图片区域,显示遮罩层;
  • 鼠标移出图片区域,隐藏遮罩层;
  • 鼠标移动,遮罩层跟随鼠标移动;
  • 遮罩层不能超出图片所在区域;
  • 遮罩层覆盖的图片区域按照指定比例放大显示;
  • 遮罩层移动,放大图跟随移动;

二、实现效果

初始效果

放大效果

三、完整代码

【test.html】

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>放大镜效果</title><style>* {margin: 0;padding: 0;}.one-img-box,.big-img-box {position: relative;width: 300px;height: 300px;box-shadow: 0 0 6px 1px #cacaca;border-radius: 10px;overflow: hidden;}.one-img-box {display: inline-block;top: 60px;left: 60px;cursor: move;}.one-img-box>img {width: 100%;height: 100%;}.big-img-box {/* display: inline-block; */display: none;top: 60px;left: 100px;}.big-img-box>img {width: 300%;height: 300%;}.big-img {position: absolute;left: 0;top: 0;}.mask {/* display: inline-block; */display: none;position: absolute;left: 0;top: 0;width: 100px;height: 100px;background-color: yellowgreen;opacity: .4;}</style>
</head><body><div class="one-img-box"><img src="D:\test\girl.png" alt=""><div class="mask"></div></div><div class="big-img-box"><img class="big-img" src="D:\test\girl.png" alt=""></div>
</body>
<script>// 1、获取元素// 获取原图的盒子var oneImgBox = document.querySelector('.one-img-box');// 获取遮罩层var mask = document.querySelector('.mask');// 获取大图盒子var bigImgBox = document.querySelector('.big-img-box');// 获取大图var bigImg = document.querySelector('.big-img');// 2、控制显示与隐藏// 2.1 鼠标经过 oneImgBox,显示 mask遮挡层 和 bigImgBox大盒子;oneImgBox.addEventListener('mouseover', function () {mask.style.display = 'inline-block';bigImgBox.style.display = 'inline-block';})// 2.2 鼠标移出 oneImgBox,隐藏 mask遮挡层 和 bigImgBox大盒子;oneImgBox.addEventListener('mouseout', function () {mask.style.display = 'none';bigImgBox.style.display = 'none';})// 3、遮罩层跟随鼠标移动oneImgBox.addEventListener('mousemove', function (e) {// 3.1 计算鼠标在盒子内的坐标var mouseX = e.pageX - oneImgBox.offsetLeft;var mouseY = e.pageY - oneImgBox.offsetTop;// 3.2 计算遮罩层的移动位置// 移动位置 = 鼠标的移动距离 - 遮罩层自己宽度\高度的一半(鼠标会在遮罩层中心位置,否则在左上角)var maskX = mouseX - mask.offsetWidth / 2;var maskY = mouseY - mask.offsetWidth / 2;// 计算结果赋给遮罩层;// mask.style.left = maskX + 'px';// mask.style.top = maskY + 'px';// 4、控制遮罩层的移动范围// 4.1 计算遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度var maskMaxX = oneImgBox.offsetWidth - mask.offsetWidth;var maskMaxY = oneImgBox.offsetHeight - mask.offsetHeight// 如果移动距离 大于 最大移动距离,则取最大的移动距离// 如果移动距离 小于 0,则取0;maskX = maskX > maskMaxX ? maskMaxX : maskX < 0 ? 0 : maskX;maskY = maskY > maskMaxY ? maskMaxY : maskY < 0 ? 0 : maskY;// 计算结果赋给遮罩层mask.style.left = maskX + 'px';mask.style.top = maskY + 'px';// 5、按比例显示大图// 5.1 放大比例 = 原图的宽度 / 大图的宽度 = 1 / 3var rate = oneImgBox.offsetLeft / bigImg.offsetWidth;// 5.2 大图的移动距离 = 遮罩层的移动距离 * 放大比例 (注意大图的移动方向与遮罩层相反)bigImg.style.left = - maskX * 3 + 'px';bigImg.style.top = - maskY * 3 + 'px';})
</script></html>

四、实现过程

1、HTML 页面结构

一个原图片的盒子【div元素】,里面放原图【img元素】和遮罩层【div元素】

一个放大后的图片盒子【div元素】,里面放大图【img元素】;

<body><div class="one-img-box"><img src="D:\test\girl.png" alt=""><div class="mask"></div></div><div class="big-img-box"><img class="big-img" src="D:\test\girl.png" alt=""></div>
</body>

2、CSS 元素样式

(1)两个盒子及图片样式

这里设置原图的宽高均为300px;大图的宽高是原图的三倍;

【 cursor: move; 】使得鼠标在移入图片变成“移动”样式;

【overflow: hidden;】使得图片超出盒子部分被隐藏(大图);

注意,大图盒子最初的的display的值应设为none,显隐性由鼠标移入或移出图片决定;

.one-img-box,
.big-img-box {position: relative;width: 300px;height: 300px;box-shadow: 0 0 6px 1px #cacaca;border-radius: 10px;overflow: hidden;
}.one-img-box {display: inline-block;top: 60px;left: 60px;cursor: move;
}.one-img-box>img {width: 100%;height: 100%;
}.big-img-box {display: inline-block;top: 60px;left: 100px;
}.big-img-box>img {width: 300%;height: 300%;
}.big-img {position: absolute;left: 0;top: 0;
}

(2)遮罩层样式

遮罩层使用绝对定位,根据鼠标的移动位置,再更改其left和top值,使遮罩层跟随鼠标移动;

注意:遮罩层最初不显示,display的值也应设为none;

.mask {display: inline-block;position: absolute;left: 0;top: 0;width: 100px;height: 100px;background-color: yellowgreen;opacity: .4;
}

注意:

原图的宽高均为300px;遮罩层的宽高均为100px;遮罩层与原图的宽高比例都是1 :3;

放大图的盒子和大图的比例需要一致(1 :3),所以大图的宽高应该均为900px;

这里的比例如果不一致,则会出现,遮罩层覆盖的内容,在大图中没有完全显示,或显示不全;当然可以自定义这个比例;

3、JavaScript动态控制

(1)获取页面元素

将页面中需要操作的元素都进行获取;

这里使用的是querySelector()方法来获取元素,是JavaScript中获取dom元素的方式之一;

<script>// 1、获取元素// 获取原图的盒子var oneImgBox = document.querySelector('.one-img-box');// 获取遮罩层var mask = document.querySelector('.mask');// 获取大图盒子var bigImgBox = document.querySelector('.big-img-box');// 获取大图var bigImg = document.querySelector('.big-img');......
</script>

(2)控制大图和遮罩层的显隐性

先设置大图盒子和遮罩层的display 为 none;

......
.big-img-box {/* display: inline-block; */display: none;......
}
.mask {/* display: inline-block; */display: none;......
}
......

分析需求可知:

  • 遮罩层和大图盒子的显示与隐藏是同时的,大图盒子显示则遮罩层显示,大图盒子隐藏则遮罩层隐藏;
  • 当鼠标经过原图时,两者显示,需要给这个原图盒子注册鼠标经过事件,完成相应功能;
  • 当鼠标移出原图时,两者隐藏,也需要给这个原图盒子注册鼠标移出事件,完成相应功能;
<script>......// 2、控制显示与隐藏// 2.1 鼠标经过 oneImgBox,显示 mask遮挡层 和 bigImgBox大盒子;oneImgBox.addEventListener('mouseover', function () {mask.style.display = 'inline-block';bigImgBox.style.display = 'inline-block';})// 2.2 鼠标移出 oneImgBox,隐藏 mask遮挡层 和 bigImgBox大盒子;oneImgBox.addEventListener('mouseout', function () {mask.style.display = 'none';bigImgBox.style.display = 'none';})......
</script>

(3)遮罩层跟随鼠标移动

分析需求可知:

  • 遮罩层在盒子内的移动距离,实际就是鼠标的移动距离(遮罩层跟着鼠标移动),但注意这个是遮罩层左上角的位置;
  • 遮罩层中心的移动距离,要在鼠标移动距离的基础上,减去遮罩层自身的宽度或高度;
  • 鼠标的移动距离mouseX\mouseY为,鼠标在页面中的X坐标\Y坐标 - 图片盒子的左\上边距;
  • 注意,这里鼠标一开始进入图片盒子就开始计算;
<script>......// 3、遮罩层跟随鼠标移动oneImgBox.addEventListener('mousemove', function (e) {// 3.1 计算鼠标在盒子内的坐标var mouseX = e.pageX - oneImgBox.offsetLeft;var mouseY = e.pageY - oneImgBox.offsetTop;// 3.2 计算遮罩层的移动位置// 移动位置 = 鼠标的移动距离 - 遮罩层自己宽度\高度的一半(鼠标会在遮罩层中心位置,否则在左上角)var maskX = mouseX - mask.offsetWidth / 2;var maskY = mouseY - mask.offsetWidth / 2;// 计算结果赋给遮罩层;mask.style.left = maskX + 'px';mask.style.top = maskY + 'px';......})
</script>

注意:

这里存在一个问题,就是当鼠标靠近图片边缘的时候,遮罩层会继续移动,被裁剪;

应该加以判断,控制遮罩层的移动范围,使得遮罩层不会被移出去;

(4)控制遮罩层移动范围

分析需求可知:

  • 遮罩层的移动距离不能小于 0,也不能超过它的最大移动距离;
  • 遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度;
  • 如果移动距离 大于 最大移动距离,则取最大的移动距离;
  • 如果移动距离 小于 0,则取0;
<script>......// 3、遮罩层跟随鼠标移动oneImgBox.addEventListener('mousemove', function (e) {......// 4、控制遮罩层的移动范围// 4.1 计算遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度var maskMaxX = oneImgBox.offsetWidth - mask.offsetWidth;var maskMaxY = oneImgBox.offsetHeight - mask.offsetHeight// 如果移动距离 大于 最大移动距离,则取最大的移动距离// 如果移动距离 小于 0,则取0;maskX = maskX > maskMaxX ? maskMaxX : maskX < 0 ? 0 : maskX;maskY = maskY > maskMaxY ? maskMaxY : maskY < 0 ? 0 : maskY;// 计算结果赋给遮罩层mask.style.left = maskX + 'px';mask.style.top = maskY + 'px';......})
</script>

(5)按比例移动放大图

分析需求可知:

  • 放大比例 = 原图的宽度 / 大图的宽度;
  • 大图的移动距离 = 遮罩层的移动距离 * 放大比例;
  • 注意:大图的移动方向与遮罩层相反;
<script>......// 3、遮罩层跟随鼠标移动oneImgBox.addEventListener('mousemove', function (e) {......// 5、按比例显示大图// 5.1 放大比例 = 原图的宽度 / 大图的宽度 = 1 / 3var rate = oneImgBox.offsetLeft / bigImg.offsetWidth;// 5.2 大图的移动距离 = 遮罩层的移动距离 * 放大比例 (注意大图的移动方向与遮罩层相反)bigImg.style.left = - maskX * 3 + 'px';bigImg.style.top = - maskY * 3 + 'px';})
</script>

=========================================================================

每天进步一点点~!

记录一下这个实用的前端"小轮子"~! 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • DNSSec:网络安全的守护者
  • GIT相关操作,推送本地分支到远程仓库流程记录学习
  • C++ 数据结构探索:构建高效程序的基础
  • 在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
  • python库(10):SpaCy库实现NLP处理
  • 【面试题】Golang(第四篇)
  • json-server服务使用教程
  • kafka 常用命令
  • 某某会员小程序后端性能优化
  • 11网络层-分组转发算法
  • 20240711每日消息队列-------------MQ消息的积压的折磨
  • html设计(两种常见的充电效果)
  • HCIA学习笔记(6)-ACL+NAT
  • LabVIEW扬尘控制系统
  • NsightCompute教程入门
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 0基础学习移动端适配
  • ECS应用管理最佳实践
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • golang中接口赋值与方法集
  • Java应用性能调优
  • k8s 面向应用开发者的基础命令
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • PHP的类修饰符与访问修饰符
  • python docx文档转html页面
  • Python学习笔记 字符串拼接
  • Vim Clutch | 面向脚踏板编程……
  • Yii源码解读-服务定位器(Service Locator)
  • 翻译--Thinking in React
  • 深度学习中的信息论知识详解
  • 使用Swoole加速Laravel(正式环境中)
  • 我是如何设计 Upload 上传组件的
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 进程与线程(三)——进程/线程间通信
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • #QT(智能家居界面-界面切换)
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (1)(1.9) MSP (version 4.2)
  • (35)远程识别(又称无人机识别)(二)
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (四)模仿学习-完成后台管理页面查询
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • . NET自动找可写目录
  • .net core Swagger 过滤部分Api
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .Net 垃圾回收机制原理(二)