js详细讲解放大镜的实现
实现放大镜的整体思路
1.当鼠标放在图片上的时候,出现蒙层。
2.出现蒙层,让鼠标在蒙层中心
3.限制蒙层移动的范围
4.放大镜移动
最终实现的效果
鼠标放上去的时候,出现一个蒙层。
蒙层的移动范围只能在图片里,不能超出范围。
移动蒙层时,右侧会出现图片的放大部分。
移除图片的范围,放大镜消失。

鼠标放上去时候出现蒙层
<style>
*{
padding: 0;
margin: 0;
}
.box{
margin-left: 400px;
margin-top: 150px;
position: relative;
}
.small-box{
position: absolute;
/* 图片的大小 */
height: 450px;
width: 450px;
}
.mask {
position: absolute;
left: 0;
top: 0;
display: none;
width: 300px;
height: 300px;
z-index: 3;
border: 1px solid #aaa;
background: 50% top no-repeat #fede4f;
opacity: .5;
-moz-opacity: .5;
-khtml-opacity: .5;
filter: alpha(Opacity=50);
cursor: move;
}
.big-box{
position: relative;
display: none;
/* 右侧放大镜盒子的大小 */
width: 500px;
height: 500px;
/* 盒子肯定比图片小,然后使用超出裁剪 */
overflow: hidden;
/* 定位右侧盒子的位置 */
top: 0px;
/* 留了一个单位的像素处来,好区别 */
left:451px;
}
#bigImg{
position: absolute;
}
.small-box:hover .mask{
display: block;
}
.small-box:hover + .big-box{
display: block;
}
</style>
<body>
<div id="box" class="box">
<!-- 页面上看见的小图 -->
<div id="smallBox" class="small-box">
<img src="https://img11.360buyimg.com/n1/s450x450_jfs/t1/125337/25/33944/39827/643cecaaFe632cc8e/b33f7ab378a5c0d3.jpg">
<div class="mask" id="mask"></div>
</div>
</div>
<!-- 放大的图 -->
<div class="big-box" id="bigBox">
<img id="bigImg" src="https://img14.360buyimg.com/n0/jfs/t1/125337/25/33944/39827/643cecaaFe632cc8e/b33f7ab378a5c0d3.jpg.avif" class="">
</div>
</div>
</body>

计算蒙层坐标的中心位置
1.我们首先要计算一个坐标点的位置。
获取蒙层坐标点的位置
let mask_x= e.pageX - box.offsetLeft
let mask_y= e.pageY - box.offsetTop
现在我们得到了坐标点的位置。
如何计算蒙层坐标的中心位置呢?
mask_x= mask_x-mask.offsetWidth/2
mask_y= mask_y-mask.offsetHeight/2
也就是将 mask_x 向左移动了mask元素宽度的一半。
特别说明:
offsetLeft 是指当前元素相对其距离自己最近的具有定位属性的父级元素的偏移值。
margin,定位,border也会影响offsetLeft的值。但是padding不会影响。

<body>
<div id="box" class="box">
<!-- 页面上看见的小图 -->
<div id="smallBox" class="small-box">
<img src="https://img11.360buyimg.com/n1/s450x450_jfs/t1/125337/25/33944/39827/643cecaaFe632cc8e/b33f7ab378a5c0d3.jpg">
<div class="mask" id="mask"></div>
</div>
<!-- 放大的图 -->
<div class="big-box" id="bigBox">
<img src="https://img14.360buyimg.com/n0/jfs/t1/125337/25/33944/39827/643cecaaFe632cc8e/b33f7ab378a5c0d3.jpg.avif" class="">
</div>
</div>
</body>
<script>
let smallBox=document.getElementById('smallBox')
let box=document.getElementById('box')
let mask=document.getElementById('mask')
smallBox.onmousemove =function(e){
// 获取蒙层坐标点的位置
let mask_x= e.pageX - box.offsetLeft
let mask_y= e.pageY - box.offsetTop
// 计算蒙层坐标点的中心位置
mask_x-= mask.offsetWidth/2
mask_y-= mask.offsetHeight/2
mask.style.left = mask_x+'px'
mask.style.top = mask_y+'px'
}
</script>

限制移动的范围
在移动蒙层的的时候,是有范围限制的。
X轴最大的范围是: smallBox.offsetWidth-mask.offsetWidth,最小范围是0;
Y轴的最大范围是: smallBox.offsetHeight-mask.offsetHeight,最小范围是0;

<script>
let smallBox=document.getElementById('smallBox')
let box=document.getElementById('box')
let mask=document.getElementById('mask')
smallBox.onmousemove =function(e){
// 获取蒙层坐标点的位置
let mask_x= e.pageX - box.offsetLeft
let mask_y= e.pageY - box.offsetTop
// 计算蒙层坐标点的中心位置
mask_x-= mask.offsetWidth/2
// mask_x-= mask.offsetWidth - mask_x /2
mask_y-= mask.offsetHeight/2
// 获取X可以移动的最大值
let moveMaxX= smallBox.offsetWidth-mask.offsetWidth
// 获取y可以移动的最大值
let moveMaxY= smallBox.offsetHeight-mask.offsetHeight
// X轴最小值和最大值
if(mask_x<0){
mask_x=0
}
if(mask_x>moveMaxX){
mask_x=moveMaxX
}
// Y轴最小值和最大值
if(mask_y<0){
mask_y=0
}
if(mask_y>moveMaxY){
mask_y=moveMaxY
}
mask.style.left = mask_x+'px'
mask.style.top = mask_y+'px'
}
</script>

大图的移动
当我们的蒙层向右移动的时候,
我们的大图实际上是向左移动的。
移动的公式:
bigImg.style.left= -mask_x *(bigBox.offsetWidth/mask.offsetWidth) + 'px'
bigImg.style.top= -mask_y *(bigBox.offsetHeight/mask.offsetHeight) + 'px'
<script>
let smallBox=document.getElementById('smallBox')
let box=document.getElementById('box')
let mask=document.getElementById('mask')
let bigBox = document.getElementById('bigBox')
smallBox.onmousemove =function(e){
// 获取蒙层坐标点的位置
let mask_x= e.pageX - box.offsetLeft
let mask_y= e.pageY - box.offsetTop
// 计算蒙层坐标点的中心位置
mask_x-= mask.offsetWidth/2
mask_y-= mask.offsetHeight/2
// 获取X可以移动的最大值
let moveMaxX= smallBox.offsetWidth-mask.offsetWidth
// 获取y可以移动的最大值
let moveMaxY= smallBox.offsetHeight-mask.offsetHeight
// X轴最小值和最大值
if(mask_x<0){
mask_x=0
}
if(mask_x>moveMaxX){
mask_x=moveMaxX
}
// Y轴最小值和最大值
if(mask_y<0){
mask_y=0
}
if(mask_y>moveMaxY){
mask_y=moveMaxY
}
mask.style.left = mask_x+'px'
mask.style.top = mask_y+'px'
// 右侧的放大图
bigImg.style.left= -mask_x *(bigBox.offsetWidth/mask.offsetWidth) + 'px'
bigImg.style.top= -mask_y *(bigBox.offsetHeight/mask.offsetHeight) + 'px'
}
</script>

js详细讲解放大镜的实现的更多相关文章
- jquery.form.js详细讲解
现在大家在在表单提交的时候都不流行中间页面做跳转(比如发布成功的提示页面),或者说这样做会降低用户体验.所以一般都是采用ajax来提交,能看到这个页面的朋友,想必对ajax提交表单已经是很熟悉了. 如 ...
- head标签详细讲解
head标签详细讲解 head位于html网页的头部,后前的标签,并以开始以结束的一html标签. Head标签位置如图: head标签示意图 head包含标签 meta,title,link,bas ...
- 详细讲解nodejs中使用socket的私聊的方式
详细讲解nodejs中使用socket的私聊的方式 在上一次我使用nodejs+express+socketio+mysql搭建聊天室,这基本上就是从socket.io的官网上的一份教程式复制学习,然 ...
- jquery插件分类与编写详细讲解
jquery插件分类与编写详细讲解 1. 插件种类 插件其实就是对现有的方法(或者叫函数)做一个封装,方便重用提高开发效率. jQeury主要有2种类型 1)实例对象方法插件 开发能让所有的j ...
- node+vue进阶【课程学习系统项目实战详细讲解】打通前后端全栈开发(1):创建项目,完成登录功能
第一章 建议学习时间8小时·分两次学习 总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章]) 视频教程地 ...
- JS详细图解作用域链与闭包
JS详细图解作用域链与闭包 攻克闭包难题 初学JavaScript的时候,我在学习闭包上,走了很多弯路.而这次重新回过头来对基础知识进行梳理,要讲清楚闭包,也是一个非常大的挑战. 闭包有多重要?如果你 ...
- vue-cli 目录结构详细讲解
https://juejin.im/post/5c3599386fb9a049db7351a8 vue-cli 目录结构详细讲解 目录 结构预览 ├─build // 保存一些webpack的初始化配 ...
- Promise入门到精通(初级篇)-附代码详细讲解
Promise入门到精通(初级篇)-附代码详细讲解 Promise,中文翻译为承诺,约定,契约,从字面意思来看,这应该是类似某种协议,规定了什么事件发生的条件和触发方法. Pr ...
- 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)
前言 本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性.框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度.本文章节结构以从易到难进行组织,建议读者按章节顺序 ...
- doT.js详细介绍
doT.js详细介绍 doT.js特点是快,小,无依赖其他插件. 官网:http://olado.github.iodoT.js详细使用介绍 使用方法:{{= }} for interpolati ...
随机推荐
- js通过className删除元素
有时候难免需要使用js进行 dom 操作:如在删除地图feature时同时得清除提示框 这个就需要使用 .parentNode.removeChild(元素) let chArr = document ...
- vue使用iframe嵌入html,js方法互调
前段时间 使用h5搞了个用cesium.js做的地图服务功能,后来想整合到vue项目,当然最简单的就是iframe直接拿来用了. 但html和vue的方法交互就是成了问题,vue调用html种方法还好 ...
- Flutter调优--深入探究MediaQuery引起界面Rebuild的原因及解决办法
前言 我们可以通过MediaQuery.of(context)方法获取到一些设备和系统的相关信息,比如状态栏的高度.当前是否是黑暗模式等等,使用起来相当方便,但是也要注意可能引起的页面rebuild问 ...
- 智慧饮水系统_Android客户端
智慧饮水系统(又名:水牛 APP) 1.介绍 该项目基于 Rfid-RC522.ESP-32 进行下位机开发,硬件模块 Rfid-RC522 主要读取用户的卡号,ESP32 单片机通过 WiFi 模块 ...
- 2023-06-09:什么是Redis事务?原理是什么?
2023-06-09:什么是Redis事务?原理是什么? 答案2023-06-09: Redis中的事务是以一组命令的形式出现的,这些命令被认为是最小的执行单位.事务可以保证在一个单独独立的隔离操作中 ...
- Go语言中的原子操作
1. 引言 在并发编程中,多个协程同时访问和修改共享数据时,如果没有使用适当的机制来防止并发问题,这个时候可能导致不确定的结果.数据不一致性.逻辑错误等严重后果. 而原子操作是解决并发编程中共享数据访 ...
- 22.04.1 wine8.10 完美安装同花顺最新版THS_9.20.40_20230613
Linux luma 5.19.0-45-generic #46~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 7 15:06:04 UTC 20 x86_64 ...
- GO 语言中 slice 的理解
GO 语言中 slice 理解 为什么说 Go 语言的 slice 是引用类型,其底层实现明明是一个结构体? slice 的底层实现是一个包含三个字段的结构体:指向底层数组的指针.slice 的长度和 ...
- Taurus .Net Core 微服务开源框架:Admin 插件【3】 - 指标统计管理
前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[2] - 系统环境信息管理 本篇继续介绍下一个内容: 1.系统指标节点:Metric - API 界面 界面图如下: ...
- Unity中的PostProcessBuild:深入解析与实用案例
Unity中的PostProcessBuild:深入解析与实用案例 在Unity游戏开发中,我们经常需要在构建完成后对生成的应用程序进行一些额外的处理.这时,我们可以使用Unity提供的PostPro ...