功能介绍
很多购物平台都会有这种放大镜效果,通过移动鼠标使图片放大,主要是方便顾客查看图片
基本原理
左右各放一个div ,里面分别放相同的图片,右边的图片像素要比左边的大,这样会更清晰
主要用的事件
mouseenter mouseleave mousemove 三个事件,简单介绍下
mouseenter
当鼠标接触到绑定元素的时候,立即触发一次,注意并不是一直触发
mouseleave
当鼠标离开绑定元素的时候,触发一次
mousemove
当鼠标在绑定元素上移动时会不断触发
为什么不用mouseover mouseout,因为在子元素或父元素都会触发这两个事件,尽量使用mouseenter,mouseleave ,不然还得阻止事件冒泡,减少不必要的麻烦
html结构如下
<div class="preview">
<img src="./img/2.jpg" alt="">
<div class="mask"></div>
<div class="big">
<img src="./img/2.jpg" alt="" class="big_img">
</div>
</div>
解释下mask盒子,就是跟着鼠标移动的黄色方块
大图片盒子要绝对定位到小图片右侧
因为我用的同一张照片,所以要给图片各自设置大小
* {
padding: 0;
margin: 0;
}
.preview {
width: 500px;
height: 500px;
margin-left: 30px;
border: 1px solid #000;
text-align: center;
position: relative;
}
.preview>img {
width: 100%;
height: 500px;
object-fit: cover;
object-position: 0 0;
}
.mask {
display: none;
width: 200px;
height: 200px;
background-color: #fede4f;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
}
.big {
display: none;
width: 500px;
height: 500px;
background-color: pink;
position: absolute;
top: 0;
left: 510px;
z-index: 999;
overflow: hidden;
}
.big>img {
width:1200px;
position: absolute;
top: 0;
left: 0;
}
js代码
$(".preview").on("mouseenter",function(){
$(".mask").show()
$(".big").show()
})
$(".preview").on("mouseleave",function(){
$(".mask").hide()
$(".big").hide()
})
mouseenter ,mouseleave只控制mask盒子和大图片的显示和隐藏
$(".preview").on("mousemove",function(e){
//在x轴移动的距离
var x=e.pageX-$('.preview').offset().left
var y=e.pageY-$('.preview').offset().top
})
e.pageX,e.pageY是 鼠标在页面中的x,y坐标
$(’.preview’).offset().left,$(’.preview’).offset().top分别是 preview盒子距离页面左边和页面上边的距离
x=e.pageX-$(’.preview’).offset().left 也就是鼠标在preview盒子中x轴移动的距离
y=e.pageY-$(’.preview’).offset().top也就是鼠标在preview盒子中y轴移动的距离
分别将 x , y的值赋给 mask盒子的left 和 top 就能实现mask盒子跟随鼠标移动
$(".mask").css("left",x+"px").css("top",y+"px")
但是会出现鼠标不在mask盒子中间
所以还要计算x,y
var maskX=x-$(".mask").width()/2
var maskY=y-$(".mask").height()/2
$(".mask").width()/2 mask盒子长度的一半
通过maskX ,maskY赋给mask移动的x,y坐标能够将mask盒子的中心跟随鼠标移动
现在看来鼠标已经在mask中心了
但是mask盒子会超出preview盒子,那可不行
可以通过console.log(maskX) 观察maskX的变化
maskX的范围要在白框宽度之间才能使mask盒子固定在preview盒子里
同理,maskY的范围要在白框高度之间才能使mask盒子固定在preview盒子里
if(maskX<=0){
maskX=0
}else if(maskX>=$('.preview').width()-$(".mask").width()){
maskX=$('.preview').width()-$(".mask").width()
}
if(maskY<=0){
maskY=0
}else if(maskY>=$('.preview').height()-$(".mask").height()){
maskY=$('.preview').height()-$(".mask").height()
}
根据上面两个图理解这两个if 代码 还是很好理解的
现在再将maskX ,maskY分别赋值给mask盒子的left 和 top
$(".mask").css("left",maskX+"px").css("top",maskY+"px")
会发现左边的功能都实现了
右边大图片的功能只需要记住一个公式就行了
大图片的移动距离=遮挡层移动距离*大图片最大移动距离/遮挡层的最大移动距离
遮挡层移动距离就是 maskX 和 maskY
大图片最大移动距离=$(’.big_img’).width()-$(".big").width()
遮挡层的最大移动距离=$(’.preview’).width()-$(".mask").width()
大图片最大移动距离 解释下 ,因为大图片要比放图片的盒子大,所以将盒子看成遮罩,移动的是图片,超出盒子的部分全部隐藏
$(".big_img").css("left",-maskX*maxBigMove/maxLittleMove+"px").css("top",-maskY*maxBigMove/maxLittleMove+"px")
到这功能就都可以实现了
js全部代码
$(document).ready(function(){
$(".preview").on("mouseenter",function(){
$(".mask").show()
$(".big").show()
})
$(".preview").on("mouseleave",function(){
$(".mask").hide()
$(".big").hide()
})
$(".preview").on("mousemove",function(e){
//在x轴移动的距离
var x=e.pageX-$('.preview').offset().left
var y=e.pageY-$('.preview').offset().top
//遮罩中心点在x轴移动的距离
var maskX=x-$(".mask").width()/2
var maskY=y-$(".mask").height()/2
// $(".mask").css("left",maskX+"px").css("top",maskY+"px")
console.log(maskX);
if(maskX<=0){
maskX=0
}else if(maskX>=$('.preview').width()-$(".mask").width()){
maskX=$('.preview').width()-$(".mask").width()
}
if(maskY<=0){
maskY=0
}else if(maskY>=$('.preview').height()-$(".mask").height()){
maskY=$('.preview').height()-$(".mask").height()
}
$(".mask").css("left",maskX+"px").css("top",maskY+"px")
// 大图片的移动距离=遮挡层移动距离*大图片最大移动距离/遮挡层的最大移动距离
// 遮罩层最大移动的距离
var maxLittleMove=$('.preview').width()-$(".mask").width()
//大图片最大移动距离
var maxBigMove=$('.big_img').width()-$(".big").width()
$(".big_img").css("left",-maskX*maxBigMove/maxLittleMove+"px").css("top",-maskY*maxBigMove/maxLittleMove+"px")
})
})