实现放大镜的整体思路

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详细讲解放大镜的实现的更多相关文章

  1. jquery.form.js详细讲解

    现在大家在在表单提交的时候都不流行中间页面做跳转(比如发布成功的提示页面),或者说这样做会降低用户体验.所以一般都是采用ajax来提交,能看到这个页面的朋友,想必对ajax提交表单已经是很熟悉了. 如 ...

  2. head标签详细讲解

    head标签详细讲解 head位于html网页的头部,后前的标签,并以开始以结束的一html标签. Head标签位置如图: head标签示意图 head包含标签 meta,title,link,bas ...

  3. 详细讲解nodejs中使用socket的私聊的方式

    详细讲解nodejs中使用socket的私聊的方式 在上一次我使用nodejs+express+socketio+mysql搭建聊天室,这基本上就是从socket.io的官网上的一份教程式复制学习,然 ...

  4. jquery插件分类与编写详细讲解

    jquery插件分类与编写详细讲解 1. 插件种类 插件其实就是对现有的方法(或者叫函数)做一个封装,方便重用提高开发效率.   jQeury主要有2种类型   1)实例对象方法插件 开发能让所有的j ...

  5. node+vue进阶【课程学习系统项目实战详细讲解】打通前后端全栈开发(1):创建项目,完成登录功能

    第一章 建议学习时间8小时·分两次学习      总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章]) 视频教程地 ...

  6. JS详细图解作用域链与闭包

    JS详细图解作用域链与闭包 攻克闭包难题 初学JavaScript的时候,我在学习闭包上,走了很多弯路.而这次重新回过头来对基础知识进行梳理,要讲清楚闭包,也是一个非常大的挑战. 闭包有多重要?如果你 ...

  7. vue-cli 目录结构详细讲解

    https://juejin.im/post/5c3599386fb9a049db7351a8 vue-cli 目录结构详细讲解 目录 结构预览 ├─build // 保存一些webpack的初始化配 ...

  8. Promise入门到精通(初级篇)-附代码详细讲解

    Promise入门到精通(初级篇)-附代码详细讲解 ​     Promise,中文翻译为承诺,约定,契约,从字面意思来看,这应该是类似某种协议,规定了什么事件发生的条件和触发方法. ​     Pr ...

  9. 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)

    前言 本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性.框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度.本文章节结构以从易到难进行组织,建议读者按章节顺序 ...

  10. doT.js详细介绍

    doT.js详细介绍   doT.js特点是快,小,无依赖其他插件. 官网:http://olado.github.iodoT.js详细使用介绍 使用方法:{{= }} for interpolati ...

随机推荐

  1. MySQL-DQL

    准备测试表,先跟着执行下面的SQL #1.登录MySQL后 #2.创建test_database数据库,不存在则创建 create database if not exists test_databa ...

  2. 图解Redis和Zookeeper分布式锁

    1.基于Redis实现分布式锁 Redis分布式锁原理如上图所示,当有多个Set命令发送到Redis时,Redis会串行处理,最终只有一个Set命令执行成功,从而只有一个线程加锁成功 2:SetNx命 ...

  3. AI 协助办公 |记一次用 GPT-4 写一个消息同步 App

    GPT-4 最近风头正劲,作为 NebulaGraph 的研发人员的我自然是跟进新技术步伐.恰好,现在有一个将 Slack channel 消息同步到其他 IM 的需求,看看 GPT-4 能不能帮我完 ...

  4. WPF中关于转换器

    实例:关于播放器按钮状态的改变 说明:对Kind(种类)的绑定首先在viewmodel中声明一个属性IsPlay,然后在转换器中实现按钮的状态 转换器 在解决方案中的项目里新建一个Converters ...

  5. LINQ检索使用

    我看网上对LINQ的讲解 自己整合了一下 是语言集成查询(Language Integrated Query)是一组用于C#和Visual Basic语言的扩展.能够允许编写C#或VB代码以查询数据相 ...

  6. CF1608F MEX counting

    题意 给定 \(n, k\) 和序列 \(b_{1\dots n}\),计数序列 \(a_{1\dots n}\) 使得 \(\forall i \in [1, n], \operatorname{m ...

  7. RTC+AI|“即智”数智人创新内容生产体验,为企业降本增效再提速

    号称"史上最卷"的618年中大促落下帷幕,几大电商巨头在直播投入和短视频内容建设上持续加码,短视频+直播电商的营销模式成为618期间的主要输出. 以某美妆专场直播间为例,主播现场手 ...

  8. The server time zone value '?泄???????' is unrecognized or represents more t

    hibernate配置文件如下 运行在服务器上,报错如下 解决方案: 在jdbc连接的url后面加上serverTimezone=GMT即可解决问题,因为是数据库和系统时区差异所造成的, 即 < ...

  9. 用 Hugging Face 推理端点部署 LLM

    开源的 LLM,如 Falcon.(Open-)LLaMA.X-Gen.StarCoder 或 RedPajama,近几个月来取得了长足的进展,能够在某些用例中与闭源模型如 ChatGPT 或 GPT ...

  10. 你的Spring应用启动很慢?不妨试试这个工具!

    睡不着闲逛,在GitHub上看到一个挺实用的开源项目:Spring Startup Analyzer. 从项目名称中就大概能猜到,这是一个分析Spring应用启动过程的工具.Spring Startu ...