之前看了pink老师的视频,做了图片的放大效果,但是只有放大效果,不完整,后来又学了轮播图案例,把这两个结合起来,试着实现了完整的放大镜效果。
因为点击左右箭头需要滚动,需要用到animate.js文件,其代码如下:
function animate(obj, target, callback) {
clearInterval(obj.timer); // 先清除以前的定时器,只保留当前的一个定时器执行
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer); // 停止动画 本质是停止定时器
callback && callback(); //如果有回调函数,则执行
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
pink老师的视频中,使用了两张图片,一大一小来实现放大。如果这样子来做的话,加上下面的小图,得需要27张图像,我这里给改了,只使用了一张428像素的图片,只不过使用css改变大小,左侧尺寸400px,右侧放大后的尺寸是800px,这样只需要18张。也就是说,需要9张78px的小图,9张428像素的大图。所用图片我是从华为网站下载的,放在images文件夹中。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>放大镜效果</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root{
--height1:70px;
}
ul,ol,li {
list-style: none;
}
.main {
width: 1200px;
margin: 0 auto;
}
.special{
height: var(--height1);
position: relative;
width: 400px; /*左右箭头各24px,列表350px,中间有2处1px的空白*/
overflow: hidden;
margin-top: 10px;
}
.focus {
width: 350px;
}
.focus ul {
width: 630px;
position: absolute; /*必须有定位*/
top: 0;
left: 25px; /*距离左端25px*/
z-index: 0;
overflow: hidden;
}
.focus li {
float: left;
width:70px;
height:var(--height1);
z-index: 0;
}
.focus li img{
width:68px;
height:68px;
}
.arrowLeft,.arrowRight {
position: absolute;
top:0px;
width: 24px;
height: 100%;
text-align: center;
z-index: 9;
cursor:pointer;
background-color: #fff;
color: #666;
font-size: 20px;
}
.arrowLeft span,.arrowRight span{
position: absolute;
top:50%;
transform: translate(0,-50%);
display: block;
width: 24px;
height: 24px;
border-radius:50% ;
border: 1px solid #ccc;
}
.arrowLeft{
left: 0;
}
.arrowRight {
right: 0;
}
.arrowLeft span em, .arrowRight span em{
display: block;
width: 12px;
height: 12px;
border-top:2px solid #ccc;
border-left:2px solid #ccc;
margin-top: 5px;
}
.arrowLeft span em{
transform: rotate(-45deg);
margin-left: 8px;
}
.arrowRight span em{
transform: rotate(135deg);
margin-left: 2px;
}
.preview_Img {
/* 图片预览区域 */
position: relative;
border: 1px solid #ccc;
width: 402px;
height: 402px;
margin-top: 100px;
}
.w400 {
width: 400px;
height: 400px;
}
.mask {
/* 遮罩层,初始状态不可见 */
position: absolute;
width: 200px;
height: 200px;
background-color: rgba(192, 192, 192, 0.5);
display: none;
}
.enlarge {
display: none;
width: 500px;
height: 500px;
position: absolute;
left: 450px;
top: 0;
border: 2px solid #ccc;
overflow: hidden;
}
.enlargeImg {
/* 加定位,放大的大图像 */
position: absolute;
width: 800px;
height: 800px;
}
</style>
<script src="js/animate.js"></script>
</head>
<body>
<div class="main">
<!-- 图片预览区域 -->
<div class="preview_Img">
<Img src="images/p1.png" alt="" class="w400"> <!-- 原始图片 -->
<div class="mask"></div> <!-- 遮罩层 -->
<div class="enlarge">
<Img src="images/p1.png" alt="" class="enlargeImg"> <!-- 放大后图片 -->
</div>
</div>
<!--小图片轮播区域 -->
<div class='special'>
<div class="arrowLeft"><span><em></em></span></div> <!-- 左侧箭头 -->
<div class="focus">
<ul>
<li><a href="javascript:;"><img src="images/small-p1.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p2.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p3.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p4.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p5.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p6.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p7.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p8.png"></a></li>
<li><a href="javascript:;"><img src="images/small-p9.png"></a></li>
</ul>
</div>
<div class="arrowRight"><span><em></em></span></div> <!-- 右侧箭头 -->
</div> <!--end special-->
</div><!--end main-->
<script>
window.onload = function() {
var preview = document.querySelector('.preview_Img');
var mask = document.querySelector('.mask');
var enlarge = document.querySelector('.enlarge');
var enlargeImg = document.querySelector('.enlargeImg');
//当鼠标经过 preview 就显示mask 遮罩层 和 enlarge 大盒子
preview.addEventListener('mouseover', function() {
mask.style.display = 'block';
enlarge.style.display = 'block';
});
// 鼠标移出图片,关闭放大镜效果
preview.addEventListener('mouseout', function() {
mask.style.display = 'none';
enlarge.style.display = 'none';
})
// 当鼠标移动的时候
preview.addEventListener('mousemove', function(e) {
// 获得遮挡层移动的距离
var maskX = e.pageX - preview.offsetLeft - mask.offsetWidth / 2;
var maskY = e.pageY - preview.offsetTop - mask.offsetHeight / 2;
// 遮挡层最大的移动距离
var maskMaxX = preview.offsetWidth - mask.offsetWidth;
var maskMaxY = preview.offsetHeight - mask.offsetHeight;
// 限制遮挡层的移动范围
if (maskX < 0) {
maskX = 0;
} else if (maskX > maskMaxX) {
maskX = maskMaxX;
}
if (maskY < 0) {
maskY = 0;
} else if (maskY >= maskMaxY) {
maskY = maskMaxY;
}
mask.style.left = maskX + 'px'; // 让放大镜跟随鼠标进行移动
mask.style.top = maskY + 'px';
var enlargeImgMax = enlargeImg.offsetWidth - enlarge.offsetWidth; // 大图片最大移动距离
// 大图片的移动距离 = 遮挡层移动距离 * 大图片的最大移动距离 / 遮挡层最大移动距离
var enlargeImgX = maskX * enlargeImgMax / maskMaxX;
var enlargeImgY = maskY * enlargeImgMax / maskMaxY;
enlargeImg.style.left = -enlargeImgX + 'px';
enlargeImg.style.top = -enlargeImgY + 'px';
});
imgArr=['images/p1.png','images/p2.png','images/p3.png','images/p4.png','images/p5.png','images/p6.png','images/p7.png','images/p8.png','images/p9.png']
//鼠标移到小图上,显示对应的大图
var alinks = document.querySelectorAll('.focus a');
var objImg=document.querySelector('.w400');
for (let i = 0; i < alinks.length; i++) {
alinks[i].addEventListener('mouseover',function(){
var path=imgArr[i];
objImg.setAttribute('src',path);
enlargeImg.setAttribute('src',path);
for (let k=0;k<alinks.length;k++){
alinks[k].parentNode.style.border='none';
}
alinks[i].parentNode.style.border='1px solid #ccc';
})
}
//点击左右箭头
var special=document.querySelector('.special');
var focus = special.querySelector('.focus');
var arrowLeft =special.querySelector('.arrowLeft');
var arrowRight = special.querySelector('.arrowRight');
var count=0;
var ul=focus.querySelector('ul');
var li=focus.querySelector('li');
var step=li.offsetWidth;
arrowRight.addEventListener('click', function() {
if (count >= 4) {
return;
}
count++;
animate(ul, -count * step+25);
})
arrowLeft.addEventListener('click', function() {
if (count <=0) {
return;
}
count--;
animate(ul, -count * step+25);
})
}
</script>
</body>
</html>