原生js实现商品放大镜效果
1 案例结构分析
- .original>img 是原图的展示界面
- .original_move 是透明正方形,通过移动获取原图的图片位置信息,从而根据位置信息来设置发大图的比例关系。
- .magnify 放大图的展示。
- .change_img 切图改变原图部分与发大图部分的src属性。
<div class="pro">
<div class="original">
<img src="../class_29/img/pic1.jpg">
<div class="original_move">
</div>
</div>
<div class="magnify">
<img src="../class_29/img/pic1.jpg">
</div>
<div class="change_img">
<img src="../class_29/img/pic1.jpg">
<img src="../class_29/img/pic2.jpg">
<img src="../class_29/img/pic3.jpg">
<img src="../class_29/img/pic4.jpg">
<img src="../class_29/img/pic5.jpg">
</div>
</div>
2 透明正方形的碰撞检测
//小方块跟随鼠标移动
original_move.style.left = e.offsetX - parseInt(getComputedStyle(original_move).width) * 0.5 + 'px';
original_move.style.top = e.offsetY - parseInt(getComputedStyle(original_move).height) * 0.5 + 'px';
//控制小方块活动区域
if (parseInt(getComputedStyle(original_move).top) <= 0) {
original_move.style.top = 0 + 'px';
}
if (parseInt(getComputedStyle(original_move).left) <= 0) {
original_move.style.left = 0 + 'px';
}
let original_move_h = original.offsetHeight - original_move.offsetHeight;
let original_move_w = original.offsetWidth - original_move.offsetWidth;
if (parseInt(getComputedStyle(original_move).top) >= original_move_h) {
original_move.style.top = original_move_h + 'px';
}
if (parseInt(getComputedStyle(original_move).left) >= original_move_w) {
original_move.style.left = original_move_w + 'px';
}
-
通过onmousemove 监听透明正方形的移动,从而获取透明正方形的坐标。
-
original_move.style.left = e.offsetX - parseInt(getComputedStyle(original_move).width) * 0.5 + ‘px’;这个是为了实现每次透明移动时,鼠标光标永远在透明正方形的中间。e.offsetX为获取鼠标光标的x轴坐标,当减去透明正方形的宽度的一半时,就会让鼠标光标在正方形x轴中间,同理y轴也是可以。
-
if (parseInt(getComputedStyle(original_move).top) <= 0) {
original_move.style.top = 0 + ‘px’;
}
if (parseInt(getComputedStyle(original_move).left) <= 0) {
original_move.style.left = 0 + ‘px’;
}
这个两个限制条件约束了,透明正方形的不能越过原图正方形的上边与左边的限制,通过top与left来限制。 -
let original_move_w = original.offsetWidth - original_move.offsetWidth; if (parseInt(getComputedStyle(original_move).left) >= original_move_w) { original_move.style.left = original_move_w + 'px'; }
(1) original.offsetWidth:原图正方形的可视宽度;(下图黄色)
(2)original_move.offsetWidth:透明正方形的可视宽度;(下图绿色)
(3)parseInt(getComputedStyle(original_move).left) : 透明正方形的移动距离
(4)original_move_w (红色部分)
- 同比例放大原图:
magnify.scrollLeft = parseInt(getComputedStyle(original_move).left) * (magnify.offsetWidth / (original_move_w));
- 通过控制放大图的scrollTop(滚动条卷去距离);
- 为什么是parseInt(getComputedStyle(original_move).left) * (magnify.offsetWidth / (original_move_w));因为original_move_w是上图1的红色部分,而magnify.offsetWidth为发大正方形图片的偏移量,通过二者的比值就可以知道发大正方形的滚动条卷去距离。
3 案例源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.pro {
width: 800px;
position: relative;
margin-left: 100px;
margin-top: 100px;
}
.original {
width: 300px;
height: 300px;
border: 10px #000000 solid;
}
.original>img {
width: 100%;
height: 100%;
}
.original_move {
width: 150px;
height: 150px;
border: 1px #000000 solid;
background-color: rgba(255, 255, 255, 0.3);
position: absolute;
top: 0;
left: 0;
pointer-events: none;
display: none;
}
.magnify {
position: absolute;
left: 310px;
top: 0;
width: 400px;
height: 400px;
overflow: hidden;
display: none;
}
.magnify>img {
width: 200%;
height: 200%;
}
//换图
.change_img {}
.change_img>img {
display: inline-block;
margin-top: 10px;
width: 50px;
height: 50px;
margin-left: 5px;
}
</style>
</head>
<body>
<div class="pro">
<div class="original">
<img src="../class_29/img/pic1.jpg">
<div class="original_move">
</div>
</div>
<div class="magnify">
<img src="../class_29/img/pic1.jpg">
</div>
<div class="change_img">
<img src="../class_29/img/pic1.jpg">
<img src="../class_29/img/pic2.jpg">
<img src="../class_29/img/pic3.jpg">
<img src="../class_29/img/pic4.jpg">
<img src="../class_29/img/pic5.jpg">
</div>
</div>
<script type="text/javascript">
//获取原图
var original = document.querySelector(".original");
var original_move = original.querySelector("div");
var original_move_img = original.querySelector("img");
var magnify = document.querySelector(".magnify");
var magnify_img = magnify.querySelector("img");
var change_img = document.querySelectorAll(".change_img>img")
// console.log(original);
// console.log(original_move);
// console.log(magnify);
//鼠标进入
original.onmouseenter = function(e) {
original_move.style.display = "block";
magnify.style.display = "block";
}
//鼠标移动
original.onmousemove = function(e) {
//小方块跟随鼠标移动
original_move.style.left = e.offsetX - parseInt(getComputedStyle(original_move).width) * 0.5 + 'px';
original_move.style.top = e.offsetY - parseInt(getComputedStyle(original_move).height) * 0.5 + 'px';
//控制小方块活动区域
if (parseInt(getComputedStyle(original_move).top) <= 0) {
original_move.style.top = 0 + 'px';
}
if (parseInt(getComputedStyle(original_move).left) <= 0) {
original_move.style.left = 0 + 'px';
}
let original_move_h = original.offsetHeight - original_move.offsetHeight;
let original_move_w = original.offsetWidth - original_move.offsetWidth;
if (parseInt(getComputedStyle(original_move).top) >= original_move_h) {
original_move.style.top = original_move_h + 'px';
}
if (parseInt(getComputedStyle(original_move).left) >= original_move_w) {
original_move.style.left = original_move_w + 'px';
}
//同比例控制大图
magnify.scrollTop = parseInt(getComputedStyle(original_move).top) * (magnify.offsetHeight / (original_move_h));
magnify.scrollLeft = parseInt(getComputedStyle(original_move).left) * (magnify.offsetWidth / (original_move_w));
}
original.onmouseleave = function(e) {
original_move.style.display = "none";
magnify.style.display = "none";
}
window.onload = function() {
//console.log(original_move_img);
for (let i of change_img) {
i.onmouseenter = function() {
original_move_img.src = i.src;
magnify_img.src = i.src;
}
}
}
</script>
</body>
</html>
4 案例视频展示
商品放大镜