1. 程式人生 > >JS放大鏡demo詳細講解

JS放大鏡demo詳細講解

前言:

此放大鏡可直接改變圖片(我是用的是zoom.jpg)使用。前提是必須跟我一樣的佈局,不然裡面的clientX和offsetLeft得作出相應改動。

前提先了解數學演算法:
    求遮罩層mask寬度  
    大圖、大圖顯示區、小圖、遮罩層
    1、小圖是大圖等比縮放的
    2、遮罩層是大圖顯示區縮放的
    小圖/大圖 = 遮罩層/大圖顯示區
        遮罩層 = 大圖顯示區*(小圖/大圖);
    ------------------------------------------------
    大圖活動區 = 大圖-大圖顯示區
    小圖活動區 = 小圖-遮罩層

    遮罩層偏移量/小圖活動區 = 大圖偏移量/大圖活動區

    大圖偏移量 = 大圖活動區*(遮罩層偏移量/小圖活動區)
    大圖偏移量 = (大圖-大圖顯示區)*(遮罩層偏移量/(小圖-遮罩層))

分解動作:
    1、佈局
    2、計算遮罩層寬高度
    3、為small繫結移入移出事件處理
    4、為small繫結滑鼠移入事件處理
        4.1、計算mask的偏移量
            (e.clientX-zoom.offsetLeft-zoom.clientLeft-mask.offsetWidth/2)
        4.2、規定mask的最大最小偏移量
        4.3、計算大圖偏移量(參照公式)

注意事項:
            1、滑鼠移入和滑鼠移動事件應該加給small
            2、offsetX/offsetY 值不準確,應該使用clientX/clientY代替

效果:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		/*整個div中只放置小顯示區域即可,大顯示區域隱藏,這樣直接對zoom設定屬性就行了*/
		.zoom{
			width: 200px;
			height: 200px;
			margin-left: 100px;
			margin-top: 100px;
			/*margin-top: 1000px;  測試有滾動條情況下反應*/
			position: relative;
			border: solid 1px #000;
		}
		.big_area{
			/*大顯示區域寬高可直接改變*/
			width: 200px;
			height: 200px;
			position: absolute;
			left: -10000px;
			top: -1px;
			border: solid 1px #000;
			overflow: hidden;
		}
		.big_area img{
			position: absolute;
			left: 0;
			top: 0;
		}
		/*遮罩層*/
		.mask{
			position: absolute;
			left: -10000px;
			top: 0;
			width: 100px;
			height: 100px;
			background: #000;
			opacity:0.65;
			filter:alpha(opacity=65);
		}
	</style>
</head>
<body>
	<div class="zoom">
		<div class="small_area">
			<img src="images/zoom.jpg" width="200" height="200" />
			<span class="mask"></span>
		</div>
		<div class="big_area">
			<img src="images/zoom.jpg" width="620" height="620">
		</div>
	</div>

	<script>
		
		// 獲取相應節點元素
		var zoom = document.querySelector('.zoom');
		var simg = document.querySelector('.small_area img');
		var bimg = document.querySelector('.big_area img');
		var big = document.querySelector('.big_area');
		var small = document.querySelector('.small_area');
		var mask = document.querySelector('.mask');

		// 設定遮罩層寬高  小圖寬 除以 大圖寬 乘以 大顯示區域邊框
		mask.style.width = (simg.offsetWidth/bimg.offsetWidth)*big.clientWidth+"px";
		mask.style.height = (simg.offsetHeight/bimg.offsetHeight)*big.clientHeight+"px";

		// 定義遮罩層最大邊距,也就是最大移動距離
		var maxW = simg.clientWidth - mask.offsetWidth;
		var maxH = simg.clientHeight - mask.offsetHeight;

		// 滑鼠移入小顯示區域發生事件:1.遮罩層顯示 2.大顯示區域顯示
		small.onmouseenter=function(){
			mask.style.left = 0;
			big.style.left = 210+"px";
		}
		// 滑鼠移入小顯示區域發生事件:1.遮罩層消失 2.大顯示區域消失
		small.onmouseleave=function(){
			mask.style.left = -10000+"px";
			big.style.left = -10000+"px";
		}
		// 滑鼠在小顯示區域移動
		small.onmousemove=function(e){
			// 解決相容問題
			e = e || window.event;
			// 定義兩個變數 讓滑鼠位置一直處於遮罩層位置中間
			var nLeft = e.pageX-zoom.offsetLeft-zoom.clientLeft-mask.offsetWidth/2;
			var nTop = e.pageY-zoom.offsetTop-zoom.clientTop-mask.offsetHeight/2;

			// 設定遮罩層永遠顯示在小顯示區域內部 也就是判斷nLeft、nTop值
			nLeft = Math.min(maxW,Math.max(0,nLeft));
			nTop = Math.min(maxH,Math.max(0,nTop));

			// 遮罩層位置
			mask.style.left = nLeft+"px";
			mask.style.top = nTop+"px";

			// 設定大圖片移動位置 跟隨遮罩層百分比移動(語法帶入)
			bimg.style.left = -(bimg.offsetWidth-big.clientWidth)*(nLeft/(simg.clientWidth-mask.offsetWidth))+"px";		
			bimg.style.top = -(bimg.offsetHeight-big.clientHeight)*(nTop/(simg.clientHeight-mask.offsetHeight))+"px";			


		}
	</script>

</body>
</html>