工欲善其事,必先利其器。想要实现某一种效果,我们必须要先了解其中的原理。
放大镜的功能就是通过获取鼠标在小图中的位置,然后根据大小图的尺寸比例换算出大图需要显示的部分,然后使用定位让大图要显示的部分出现在右边的边框内。
然后看代码,根据代码看讲解会更容易理解。
html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>放大镜效果</title>
<link rel="stylesheet" href="magnifier.css">
</head>
<body>
<div id="wrapper">
<!--小图-->
<div id="img_min">
<!--图片-->
<img src="test.jpg" alt="min">
<!--跟随鼠标的白块-->
<p id="mousebg"></p>
</div>
<!--大图-->
<div id="img_max"><img id="img2_img" src="test.jpg" alt="max"></div>
</div>
<script type="text/javascript" src="magnifier.js"></script>
</body>
</html>
css部分
*{
margin: 0;
padding: 0;
}
div{
position: relative;
}
div>div{
width: 300px;
height: 300px;
float: left;
margin: 100px;
overflow: hidden;
}
#img_min>img{
/*display: block;*/
width: 300px;
}
#img_max{
display: none;
}
#img_max>img{
position: absolute;
top: 0;
left: 0;
display: block;
width: 1500px;
}
#mousebg{
display: none;
position: absolute;
width: 60px;
height: 60px;
background-color: rgba(255,255,255,.7);
top: 0;
left: 0;
}
最重要的javascript部分
window.onload = function () {
var img1 = document.getElementById('img_min');//小图盒子
var img2 = document.getElementById('img_max');//大图盒子
var img2_img = document.getElementById('img2_img');//大图图片
var wrap = document.getElementById('wrapper');
var mousebg = document.getElementById('mousebg');//鼠标白块
var mul = 5;
//当某一个模块dispaly:none的时候不能使用offsetWidth获取它的宽高
img1.onmouseover = function () {
//鼠标进入
img2.style.display = 'block';
mousebg.style.display = 'block';
}
img1.onmouseout = function () {
//鼠标离开
img2.style.display = 'none';
mousebg.style.display = 'none';
}
img1.onmousemove = function (event) {
var _event = event||window.event;//兼容性处理
var mouseX = _event.clientX - wrap.offsetLeft - img1.offsetLeft;
//计算鼠标相对与小图的位置
var mouseY = _event.clientY - wrap.offsetTop - img1.offsetTop;
//特殊情况处理,分别靠近四条边的时候
if(mouseX<mousebg.offsetWidth/2){
mouseX = mousebg.offsetWidth/2;
}
if(mouseX>img1.offsetWidth-mousebg.offsetWidth/2){
mouseX = img1.offsetWidth-mousebg.offsetWidth/2;
}
if(mouseY<mousebg.offsetHeight/2){
mouseY = mousebg.offsetHeight/2;
}
if(mouseY>img1.offsetHeight-mousebg.offsetHeight/2){
mouseY = img1.offsetHeight-mousebg.offsetHeight/2;
}
//计算大图的显示范围
img2_img.style.left = -mul*mouseX+img2.offsetWidth/2+"px";
img2_img.style.top = -mul*mouseY+img2.offsetHeight/2+"px";
//使鼠标在白块的中间
mousebg.style.left = mouseX-mousebg.offsetWidth/2+"px";
mousebg.style.top = mouseY-mousebg.offsetHeight/2+"px";
}
}
如果你看完代码和注释已经理解了,用李云龙的一句话说:“哎呀,你小子tnd还真是个天才”。那么下面的解析部分你快速的浏览完就OK了。
解析部分:
html和css部分都是简单的布局代码,不再讲解,js部分代码也比较简单,我们直接讲解鼠标移动事件部分的代码。
首先用一张图来解释一下获取鼠标相对与小图位置的原理
可以看到通过代码中的运算,我们所获取的值就是鼠标相对于img1左上角的值。
理解了这一步之后,其实可以说我们的工作已经完成了一半了。
然后,我们先跳过特殊情况的处理,直接进行右边图片定位的基本运算。
因为有用到offsetWidth、offsetHeight、style.width、style.height属性,其中style.width、style.height和offsetWidth、offsetHeight的范围是相同的,其他不同我会在另一篇博客中详细描述。我们先用一张图了解下这几个属性,同时和上面的几个属性进行对比(图片来自互联网,侵删)
然后我们讲解代码
右边大图框中的图片使用style.left定位在大图框中的位置,负号是因为我们鼠标的运动方向刚好是和我们大图框中的图片运动的方向相反,mul则是根据大图和小图的尺寸计算出来的比例,-mul*mouseX计算出来的其实就是图片在大图框中的相对位置,但是此时你会发现你鼠标所在的位置在右边是在图框的左上角的,所以我们要加上一个 img2.offsetWidth/2 来让图片居中显示。同样我们在纵坐标进行相同的处理就好了。
//计算大图的显示范围
img2_img.style.left = -mul*mouseX+img2.offsetWidth/2+"px";
img2_img.style.top = -mul*mouseY+img2.offsetHeight/2+"px";
下面我们就要进行特殊情况的处理了,做到上一步的时候你会发现,在鼠标移动到边缘的时候,鼠标那个小白块有时候会跑出图片的范围,所以我们就要进行处理将它限制在图片的范围内,因为鼠标是在白色透明块的中间,所以我们就是将鼠标限制在距离图片边框上下左右二分之一白块长/宽的位置即可。
//特殊情况处理,分别靠近四条边的时候
if(mouseX<mousebg.offsetWidth/2){
mouseX = mousebg.offsetWidth/2;
}
if(mouseX>img1.offsetWidth-mousebg.offsetWidth/2){
mouseX = img1.offsetWidth-mousebg.offsetWidth/2;
}
if(mouseY<mousebg.offsetHeight/2){
mouseY = mousebg.offsetHeight/2;
}
if(mouseY>img1.offsetHeight-mousebg.offsetHeight/2){
mouseY = img1.offsetHeight-mousebg.offsetHeight/2;
}
当距离左边小于二分之一宽的时候,我们就让mouseX等于二分之一宽,这样白块就不会继续移动,其他三个方向同理。
做完这一步,我们的效果也就全部完成了。
ps:抽象的地方可以通过画图来帮助理解