學習該特效須要掌握client、offset系列的知識,不然會有點混亂,能夠看我以前寫的文章精講-offset系列、scroll系列、client系列~,再來學習該文章,這樣會好不少哦~html
首先佈局上,很明顯要準備兩個基本的容器,一個small,一個big,還要準備兩張徹底相同的圖片,可是尺寸不一樣,每一個容器中放入相應大小的圖片,可是小的容器中還要放入一個能夠移動的遮罩。其次就是在實現上,可根據如下步驟來一步一步完成。git
佈局代碼:bash
<div id="box">
<div id="small">
<img src="./images/small.png" width="350" alt="">
<div id="mask"></div>
</div>
<div id="big">
<img src="./images/big.jpg" width="800" alt="">
</div>
</div>
複製代碼
代碼的樣式最後會貼上,不要着急~佈局
接下來,咱們註冊鼠標進入事件(在box中便可):post
box.onmouseover=function(){
mask.style.display='block';
big.style.display='block';
}
複製代碼
註冊鼠標離開事件:學習
box.onmouseout=function(){
mask.style.display='none';
big.style.display='none';
}
複製代碼
再接下來,就是重難點了,須要好好理解與消化~網站
第一步: 爲小的容器註冊移動事件,而且讓mask隨着鼠標的移動而移動:spa
small.onmousemove=function(e){
var x = e.clientX;
var y = e.clientY;
mask.style.left = x +'px';
mask.style.top= y +'px';
}
複製代碼
效果以下:code
問題: 會發現鼠標跟mask並無連在一塊兒,而是在它的左上方,那是什麼緣由致使了這個問題呢?cdn
答案:
在給box的樣式設置中加了這個margin的屬性,因此下面咱們要把這個值減掉,此時鼠標就在mask的左上角啦~
small.onmousemove=function(e){
var x = e.clientX;
var y = e.clientY;
x = x - 50;
y = y - 50;
mask.style.left = x +'px';
mask.style.top= y +'px';
}
複製代碼
第二步: 讓鼠標在mask的中心位置顯示:
要想實現該效果,很明顯,只須要讓mask向左移動自身寬度的1/2,向上移動高度的1/2便可
small.onmousemove=function(e){
var x = e.clientX-mask.offsetWidth/2;
var y = e.clientY-mask.offsetHeight/2;
x = x - 50;
y = y - 50;
mask.style.left = x +'px';
mask.style.top= y +'px';
}
複製代碼
到此,會發現一直存在的一個問題:mask能夠在頁面的任何位置移動,顯然這並不符合咱們的需求,咱們只須要它在small中移動。
第三步: 讓mask只在small所在區域移動,不能夠在這以外的區域移動
若要實現這樣的效果,那必然會有一個移動的最大值,也有一個移動的最小值。當超過這個最大值時,就不能夠繼續移動了,而是保持這個最大值,若沒有超過,就是保留當前這個值,若小於這個最小值,也不能夠繼續移動了,而是保持這個最小值~
爲了你們更直觀的理解,下面我畫圖來爲你們解釋一下:
small.onmousemove=function(e){
var x = e.clientX-mask.offsetWidth/2;
var y = e.clientY-mask.offsetHeight/2;
x = x - 50;
y = y - 50;
//最小值
x = x < 0 ? 0 : x;
y = y <0 ? 0 : y;
//最大值
x = x > small.offsetWidth-mask.offsetWidth ? small.offsetWidth-mask.offsetWidth : x;
y = y > small.offsetHeight-mask.offsetHeight ? small.offsetHeight-mask.offsetHeight : y;
mask.style.left = x +'px';
mask.style.top= y +'px';
}
複製代碼
到此,mask已經不能在small以外的地方移動了,並且鼠標也在mask中心位置~
第四步: mask在small上移動,big上等比例展現相應的部分
若要實現這個效果,則要弄明白一個比例關係式,我先舉個例子:
我之因此舉這個例子,就是由於small與big之間也存在一個對應的比例關係,這也是放大鏡特效實現的最關鍵的地方。
咱們能夠知道mask移動的距離與最大距離,也能夠知道大圖移動的最大距離,只須要求大圖移動的距離便可!
比例: mask的移動距離/大圖的移動距離=mask的最大移動距離/大圖的最大移動距離
因此:大圖的移動距離=mask的移動距離*大圖的最大移動距離/mask的最大移動距離
以橫座標爲例:
因此大圖移動的距離就能夠算出來了~
以上,第一點mask的移動距離 和第三點mask的最大移動距離上面都解釋過了,可是這個大圖的最大移動距離可能有些人還不能理解,那我這裏來解釋一下,大圖的容器box的寬度沒有大圖的寬度大,這樣就很好理解了吧~
small.onmousemove=function(e){
var x = e.clientX-mask.offsetWidth/2;
var y = e.clientY-mask.offsetHeight/2;
x = x - 50;
y = y - 50;
//最小值
x = x < 0 ? 0 : x;
y = y <0 ? 0 : y;
//最大值
x = x > small.offsetWidth-mask.offsetWidth ? small.offsetWidth-mask.offsetWidth : x;
y = y > small.offsetHeight-mask.offsetHeight ? small.offsetHeight-mask.offsetHeight : y;
mask.style.left = x +'px';
mask.style.top= y +'px';
var maskMoveMaxX = small.offsetWidth - mask.offsetWidth;
var maskMoveMaxY = small.offsetHeight - mask.offsetHeight;
var bigMoveMaxX = big.children[0].offsetWidth - big.offsetWidth;
var bigMoveMaxY = big.children[0].offsetHeight - big.offsetHeight;
var bigImgX = x * bigMoveMaxX / maskMoveMaxX;
var bigImgY = y * bigMoveMaxY / maskMoveMaxY;
}
複製代碼
第五步:將大圖移動的距離賦值給負margin:
這裏你們可能會有疑惑, (1)爲何是負margin?
你們能夠進一些購物網站看一下放大鏡的效果,當mask在小圖上向右移動時,其實大圖是向左移動的,則方向是反的,因此固然是負margin咯~
(2)那爲何要將計算的結果賦值給margin,而不是left,或者top呢?
你們能夠先試一下,試一下就知道爲何了。由於咱們只是給big設置了定位,它脫離了文檔流,可是裏面的內容並無脫離文檔流,因此left與top的值不起做用,因此咱們用margin.
small.onmousemove=function(e){
var x = e.clientX-mask.offsetWidth/2;
var y = e.clientY-mask.offsetHeight/2;
x = x - 50;
y = y - 50;
//最小值
x = x < 0 ? 0 : x;
y = y <0 ? 0 : y;
//最大值
x = x > small.offsetWidth-mask.offsetWidth ? small.offsetWidth-mask.offsetWidth : x;
y = y > small.offsetHeight-mask.offsetHeight ? small.offsetHeight-mask.offsetHeight : y;
mask.style.left = x +'px';
mask.style.top= y +'px';
var maskMoveMaxX = small.offsetWidth - mask.offsetWidth;
var maskMoveMaxY = small.offsetHeight - mask.offsetHeight;
var bigMoveMaxX = big.children[0].offsetWidth - big.offsetWidth;
var bigMoveMaxY = big.children[0].offsetHeight - big.offsetHeight;
var bigImgX = x * bigMoveMaxX / maskMoveMaxX;
var bigImgY = y * bigMoveMaxY / maskMoveMaxY;
big.children[0].style.marginLeft = -bigImgX +'px';
big.children[0].style.marginTop = -bigImgY +'px';
}
複製代碼
好啦,到這裏全部的邏輯代碼都結束啦,但願對你有所幫助~
那樣式代碼我這裏就不貼了,你們能夠去個人碼雲上下載下來碼雲