前言
这段时间事情还蛮多的,还没时间写文章。 这三天有点空闲,所以就趁着这个空闲时间写一篇文章。 本文主要内容是介绍天猫放大镜的疗效是如何实现的。 相信很多同事对此并不陌生。 这个看似很复杂的小函数,其实原理很简单。 我们来了解一下天猫放大镜的功效是如何实现的。
实施流程项目结构
我们整个项目结构并不复杂jquery 图片放大 鼠标,由images目录、jquery-3.2.1.min.js、style.css、main.js、index.html等内容组成。
素材小图(small.jpg)
原始图像(big.jpg)
放大镜背景图像 (mask_bg.jpg)
实现原理
总体原理如下:
表达式为:小方块1的左值(或上值)/小方块4的左值(或上值)=(-1)*小方块2的长度/小方块4的长度。这里是小方块1的定位父为小方块2,小方块4的定位父为小方块3。另外,小图的长宽与左窗口的长宽一致。 我们根据小方块1的顶部值和左侧值等比例改变小方块4的顶部值和左侧值,但超出小方块的部分是不可见的,这样就可以达到放大镜的效果。
文件内容 HTML
仿淘宝放大镜效果
CSS
#container{
position: relative;
}
.leftView{
position: relative;
width: 418px;
height: 418px;
}
.smallImg{
max-height: 100%;
max-width: 100%;
}
.mask{
display: none;
position: absolute;
background: url(./images/mask_bg.png);
cursor: move;
}
.rightView{
position: absolute;
left:458px;
top:0;
width:418px;
height:418px;
overflow:hidden;
}
.bigImg{
position: absolute;
top:0;
left:0;
}
每个JS模块实现了放大镜长宽的估计
这里我们解释一下为什么需要动态估计放大镜的长度和宽度。 主要原因是原始图像的长宽不确定。 并且我们需要满足放大镜/右窗口=左窗口/原始图像。 左窗口和右窗口的长和宽是确定的jquery 图片放大 鼠标,因此需要根据原始图像的长和宽来估计放大镜的长和宽。
function calculateMaskWH(){
var width=$('.leftView').width()/$('.bigImg').width()*$('.rightView').width();
var height=$('.leftView').height()/$('.bigImg').height()*$('.rightView').height();
$('.mask').css({
"width":width,
"height":height
});
}
窃听左窗口 mouseover 和 mouseout 争议
当键盘未悬浮在左窗口上时,放大镜、右窗口和原始图像不可见。 当鼠标悬停在左侧窗口时,可以看到放大镜、右侧窗口和原始图像。
//监听鼠标mouseover事件
$('.leftView').on('mouseover',function(){
$('.mask').css('display','block');
$('.rightView').css('display','block');
});
//监听鼠标mouseout事件
$('.leftView').on('mouseout',function(){
$('.mask').css('display','none');
$('.rightView').css('display','none');
});
窃听左窗mousemove争议
为了窃听 mousemove 事件,我们需要做两件事。 首先是动态改变放大镜的top和left值。 第二件事就是根据放大镜的top和left值按比例改变原图的top和left值。 所以我们这里的困难是如何估计顶部和左侧的值。 另外,还要保证放大镜不能把球扔出界外。
$('.leftView').on('mousemove',function(event){
//计算放大镜的left值和top值
var left=event.pageX-$(this).offset().left-$('.mask').width()/2;
var top=event.pageY-$(this).offset().top-$('.mask').height()/2;
//判断放大镜左右是否出界
if(left$(this).width()-$('.mask').width()){
left=$(this).width()-$('.mask').width();
}
//判断放大镜上下是否出现
if(top$(this).height()-$('.mask').height()){
top=$(this).height()-$('.mask').height();
}
$('.mask').css({
left:left+'px',
top:top+'px'
});
//计算比例
var rate=$('.bigImg').width()/$('.leftView').width();
$('.bigImg').css({
left:-rate*left+'px',
top:-rate*top+'px'
});
});
JS完整代码
$(function(){
//计算放大镜的长宽
calculateMaskWH();
//监听鼠标mouseover事件
$('.leftView').on('mouseover',function(){
$('.mask').css('display','block');
$('.rightView').css('display','block');
});
//监听鼠标mouseout事件
$('.leftView').on('mouseout',function(){
$('.mask').css('display','none');
$('.rightView').css('display','none');
});
$('.leftView').on('mousemove',function(event){
//计算放大镜的left值和top值
var left=event.pageX-$(this).offset().left-$('.mask').width()/2;
var top=event.pageY-$(this).offset().top-$('.mask').height()/2;
//判断放大镜左右是否出界
if(left$(this).width()-$('.mask').width()){
left=$(this).width()-$('.mask').width();
}
//判断放大镜上下是否出现
if(top$(this).height()-$('.mask').height()){
top=$(this).height()-$('.mask').height();
}
$('.mask').css({
left:left+'px',
top:top+'px'
});
//计算比例
var rate=$('.bigImg').width()/$('.leftView').width();
$('.bigImg').css({
left:-rate*left+'px',
top:-rate*top+'px'
});
});
//计算机放大镜的长宽
function calculateMaskWH(){
var width=$('.leftView').width()/$('.bigImg').width()*$('.rightView').width();
var height=$('.leftView').height()/$('.bigImg').height()*$('.rightView').height();
$('.mask').css({
"width":width,
"height":height
});
}
});
最终功效展示