原生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';
				}
  1. 通过onmousemove 监听透明正方形的移动,从而获取透明正方形的坐标。

  2. original_move.style.left = e.offsetX - parseInt(getComputedStyle(original_move).width) * 0.5 + ‘px’;这个是为了实现每次透明移动时,鼠标光标永远在透明正方形的中间。e.offsetX为获取鼠标光标的x轴坐标,当减去透明正方形的宽度的一半时,就会让鼠标光标在正方形x轴中间,同理y轴也是可以。

  3. 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来限制。

  4.  		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 (红色部分)

图1

  1. 同比例放大原图:
    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 案例视频展示

商品放大镜

猜你喜欢

转载自blog.csdn.net/qq_40994735/article/details/108022454