图片放大镜
思路
准备三张图片,小-中-大。
小图:缩略图,用于展示缩略部分。
中图:展示的图片,放大镜滑动的底图。
大图:放大区域的图片。
核心点:
放大镜跟随鼠标移动,并且鼠标永远处于正中间。
放大镜边界区域判断
根据鼠标移动的x,y的偏移量,同步大图的背景的偏移量。
1. 初始化
动态生成图片的缩略图
默认选中第一个元素
2. 交互
鼠标mousemove事件:
计算遮罩层位置
鼠标x - 图片左侧距离 - 放大镜宽度/2
js// 根据鼠标位置计算遮罩层的位置 var left = e.clientX - midImg.offsetLeft - mask.offsetWidth / 2; // 同理 var top = e.clientY - midImg.offsetTop - mask.offsetHeight / 2;移动边界判断
x,y方向最小: 0
x,y最大: 图片自身宽度/高度 - 遮罩层自身宽度/高度
同步放大区域的偏移量
放大区域的背景图位置就是上面计算出来的遮罩层的left和top,同步即可。
鼠标移出mouseleave
隐藏遮罩层和大图区域
点击缩略图
替换底图和大图
代码实现
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<!--最外层容器 -->
<div class="container">
<!-- 左侧原图 -->
<div class="left-img">
<!-- 遮罩层 -->
<div class="mask"></div>
</div>
<!-- 右侧放大图片 -->
<div class="right-img"></div>
<!-- 缩略图集合 -->
<div class="img-list-wrapper">
<ul class="img-list">
</ul>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>css
* {
margin: 0;
padding: 0;
list-style: none;
}
.container {
width: 1000px;
height: 600px;
margin: 50px auto;
font-size: 0;
}
.left-img {
width: 490px;
height: 510px;
margin-right: 16px;
border: 1px solid #eee;
display: inline-block;
/* 图片 */
background-image: url(./images/imgA_2.jpg);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
/* 遮罩层相对我进行定位 */
position: relative;
}
.mask {
width: 230px;
height: 230px;
background-image: url(./images/bg.png);
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.right-img {
width: 490px;
height: 510px;
border: 1px solid #eee;
display: inline-block;
background-image: url(./images/imgA_3.jpg);
background-repeat: no-repeat;
opacity: 0;
}
.img-list-wrapper {
width: 490px;
text-align: center;
margin-top: 10px;
}
.img-list {
display: inline-block;
}
.img-list li {
display: inline-block;
width: 60px;
height: 60px;
margin: 0 5px;
cursor: pointer;
/* background-image: url(./images/imgA_1.jpg); */
background-repeat: no-repeat;
/* border: 2px solid #000; */
border: 1px solid #eee;
}js
/* 工具 */
// 单一元素
function $(selector) {
return document.querySelector(selector);
}
// 多个元素
function $$(selector) {
return document.querySelectorAll(selector);
}
/* 初始化 */
var imgs = {
// 小图
small: ['imgA_1.jpg', 'imgB_1.jpg', 'imgC_1.jpg'],
// 中图
middle: ['imgA_2.jpg', 'imgB_2.jpg', 'imgC_2.jpg'],
// 大图
large: ['imgA_3.jpg', 'imgB_3.jpg', 'imgC_3.jpg']
}
// 获取一些将要使用的dom元素
var container = $('.container');
var largeImg = $('.right-img');
var midImg = $('.left-img');
var smallImg = $('.img-list');
var mask = $('.mask');
// 初始化页面函数
function initPage() {
var str = '';
for (var i = 0; i < imgs.small.length; i++) {
str += '<li style="background-image: url(./images/' + imgs.small[i] + ');"></li>'
}
smallImg.innerHTML = str;
// 2. 默认选中第一个缩略图
$('.img-list li').style.border = '2px solid #000';
}
/* 交互 */
// 绑定事件
function bindEvent() {
// 点击缩略图
smallImg.onclick = function (e) {
// 判断我点击的元素是li元素
if (e.target.tagName == 'LI') {
// 让所有li元素取消border
var lis = $$('li');
for (var i = 0; i < lis.length; i++) {
lis[i].style.border = 'none';
}
// 让选中的li元素添加border
e.target.style.border = '2px solid #000';
// 点击缩略图后,原图和大图也需要跟着变换,
// 点的是第几个元素, 获取元素索引
// [1,2,3].indexOf(3) == 2
var index = [].indexOf.call(lis, e.target);
midImg.style.backgroundImage = 'url(./images/' + imgs.middle[index] + ')';
largeImg.style.backgroundImage = 'url(./images/' + imgs.large[index] + ')';
}
}
// 鼠标移入
midImg.onmousemove = function (e) {
// 让遮罩层和大图展示
mask.style.opacity = 1;
largeImg.style.opacity = 1;
// 根据鼠标位置计算遮罩层的位置
var left = e.clientX - midImg.offsetLeft - mask.offsetWidth / 2;
// 同理
var top = e.clientY - midImg.offsetTop - mask.offsetHeight / 2;
// 边界条件
if (left <= 0) {
left = 0;
}
if (top <= 0) {
top = 0;
}
if (left >= midImg.offsetWidth - mask.offsetWidth) {
left = midImg.offsetWidth - mask.offsetWidth
}
if (top >= midImg.offsetHeight - mask.offsetHeight) {
top = midImg.offsetHeight - mask.offsetHeight
}
// 根据top和left调整mask的位置
mask.style.left = left + 'px';
mask.style.top = top + 'px';
// 根据top 和 left,修改大图的位置,background-position-x
largeImg.style.backgroundPositionX = -left + 'px';
largeImg.style.backgroundPositionY = -top + 'px';
}
// 鼠标移出
midImg.onmouseleave = function (e) {
// 让遮罩层和大图消失
mask.style.opacity = 0;
largeImg.style.opacity = 0;
}
}
function main() {
initPage();
bindEvent();
}
main();