Javascript實例項目放大鏡特效的實現流程

前言

本票博客主要是放大鏡案例,裡面涉及到的知識點會提出來,可放心食用~後有源代碼。

案例:仿京東放大鏡效果

效果見下圖:

功能要求:

當鼠標移動到小圖片上時,遮罩層出現,同時旁邊大圖片也出現,鼠標移出,遮罩層消失,大圖片也消失。遮罩層隻能在小盒內子移動,不能超出。遮罩層在小盒子內移動,大圖片顯示對應的板塊。

案例分析:

元素的隱層和顯示遮罩層的移動范圍用offset計算計算出大盒子內移動的距離

案例代碼:

首先咱們應該將結構搭建好,結構大致為:

先將各個盒子的樣式全部書寫完畢後,把藍色遮罩層盒子和右邊的裝紅色大圖片的盒子隱藏起來,註意,紫色的盒子是相對定位,所有盒子的定位都是根據紫色盒子進行定位的。

代碼如下:

<div class="box">        <img src="./image/pic1.jpg" alt="" class="box_pic">        <div class="mask"></div>        <div class="big">            <img src="./image/bigimg.jpg" alt="" class="bigImg">        </div></div>

搭建好後,我們給這個box盒子添加鼠標移動事件,當鼠標移動到box上時,mask盒子和big盒子出現,鼠標移出後,mask盒子和big盒子消失。

代碼如下:

  var pic = document.querySelector('.box');        var mask = document.querySelector('.mask');        var big = document.querySelector('.big');        //出現 消失        pic.addEventListener('mouseenter', function () {            mask.style.display = 'block';            big.style.display = 'block';        })        pic.addEventListener('mouseleave', function () {            mask.style.display = 'none';            big.style.display = 'none';        })

接著我們就需要計算一下遮罩層可以移動的距離。

由上圖可見,因為我們要求遮罩層不能超出小盒子的范圍,所以遮罩層能在小盒子內移動的距離就隻有小盒子的寬度減去遮罩層盒子的寬度,此時我們使用offset中的屬性。

offset系列

使用 offset系列相關屬性可以動態的得到該元素的位置(偏移)、大小等

offset系列屬性:

註意:offset系列隻有offsetTop和offsetLeft!!!且返回的值是不帶單位的。

對比:offset和style屬性

offset

styleoffset 可以得到任意樣式表中的樣式值style 隻能得到行內樣式表中的樣式值

offset 系列獲得的數值是沒有單位的

style.width 獲得的是帶有單位的字符串 offsetWidth 包含padding+border+widthstyle.width 獲得不包含padding和border 的值offsetWidth 等屬性是隻讀屬性,隻能獲取不能賦值style.width 是可讀寫屬性,可以獲取也可以賦值總結:適合獲取元素大小位置總結:適合給元素更改值

那麼接下來我們先使用e.pageX和e.pageY獲取到鼠標當前的坐標,得到之後用e.pageX-box.offsetLeft得到的就是盒子裡面的鼠標的位置瞭,話不多說,看圖解!

黑線-紅線得到的距離就是當前鼠標在盒子內的位置。另外 由於遮罩層是一個盒子,鼠標定位是緊貼著盒子的左上角的,我們需要將盒子往上移動50%,往右移動50%,讓鼠標與盒子的中心點對齊。最後我們得到鼠標的位置,並且判斷當前是否處於盒子內部,即判斷這個移動的位置是否處於大於0且小於最大移動距離之間。

代碼如下:

 pic.addEventListener('mousemove', function (e) {            var x = e.pageX - this.offsetLeft;            var y = e.pageY - this.offsetTop;            // mask移動距離            var maskX = x - mask.offsetWidth / 2;            var maskY = y - mask.offsetHeight / 2;            var maskMax = pic.offsetWidth - mask.offsetWidth;            // 判斷是否在盒子內部            if (maskX <= 0) {                maskX = 0;            } else if (maskX >= maskMax) {                maskX = maskMax;            }            if (maskY <= 0) {                maskY = 0;            } else if (maskY >= maskMax) {                maskY = maskMax;            }            mask.style.left = maskX + 'px';            mask.style.top = maskY + 'px';}

現在我們可以看到遮罩層可以在盒子內部移動,並且不會超出盒子的范圍,那麼本項目就到瞭最後一步,即讓旁邊的大盒子裡的圖片能夠顯示出對應的區塊。

因為兩張圖片的比例相同,我們可以按照下圖公式進行計算:

即:大圖片的移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離

代入公式,我們就可以得到大圖片的移動距離。註意,當我們鼠標從左往右滑時,大圖片應該是從右往左移,所以應該是負值。

代碼如下:

 //  大圖片的最大移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離            var bigImg = document.querySelector('.bigImg');            bigMax = bigImg.offsetWidth - big.offsetWidth;            var bigX = maskX * bigMax / maskMax;            var bigY = maskY * bigMax / maskMax;            bigImg.style.left = -bigX + 'px';            bigImg.style.top = -bigY + 'px';

至此,我們放大鏡的項目就完成啦,一步一步解析下來還是很簡單的!主要是使用瞭offset系列屬性,那麼介紹瞭offset系列屬性,不介紹一下他的另外兩個小夥伴怎麼能行?補充介紹一下client系列和scroll系列。

完整代碼如下:

<!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>    <style>        .box {            position: relative;            margin: 30px;            width: 300px;            height: 300px;            /* pointer-events: none; */            /* cursor: alias; */            /* cursor: default; */        }        .box_pic {            width: 300px;            height: 300px;            border: 1px solid #ccc;        }        .mask {            display: none;            position: absolute;            top: 0;            left: 0;            width: 200px;            height: 200px;            background-color: rgb(54, 240, 240);            opacity: 0.5;            cursor: all-scroll;            z-index: 9;        }        .big {            display: none;            position: absolute;            top: 0;            left: 320px;            width: 500px;            height: 500px;            overflow: hidden;            border: 1px solid #ccc;        }        .big img {            position: absolute;            width: 800px;            height: 800px;        }    </style></head><body>    <div class="box">        <img src="./image/pic1.jpg" alt="" class="box_pic">        <div class="mask"></div>        <div class="big">            <img src="./image/bigimg.jpg" alt="" class="bigImg">        </div>    </div>    </div>    <script>        var pic = document.querySelector('.box');        var mask = document.querySelector('.mask');        var big = document.querySelector('.big');        //出現 消失        pic.addEventListener('mouseenter', function () {            mask.style.display = 'block';            big.style.display = 'block';        })        pic.addEventListener('mouseleave', function () {            mask.style.display = 'none';            big.style.display = 'none';        })        // 移動        //獲取鼠標位置        pic.addEventListener('mousemove', function (e) {            var x = e.pageX - this.offsetLeft;            var y = e.pageY - this.offsetTop;            // mask移動距離            var maskX = x - mask.offsetWidth / 2;            var maskY = y - mask.offsetHeight / 2;            var maskMax = pic.offsetWidth - mask.offsetWidth;            // 判斷是否在盒子內部            if (maskX <= 0) {                maskX = 0;            } else if (maskX >= maskMax) {                maskX = maskMax;            }            if (maskY <= 0) {                maskY = 0;            } else if (maskY >= maskMax) {                maskY = maskMax;            }            mask.style.left = maskX + 'px';            mask.style.top = maskY + 'px';            //  大圖片的最大移動距離 = 遮擋層移動距離 * 大圖片最大移動距離 / 遮擋層的最大移動距離            var bigImg = document.querySelector('.bigImg');            bigMax = bigImg.offsetWidth - big.offsetWidth;            var bigX = maskX * bigMax / maskMax;            var bigY = maskY * bigMax / maskMax;            bigImg.style.left = -bigX + 'px';            bigImg.style.top = -bigY + 'px';        })    </script></body></html>

client系列

使用 client 系列的相關屬性來獲取元素可視區的相關信息。

client系列屬性:

註意:client包含padding值,返回值也不帶單位。

scroll系列

使用 scroll 系列的相關屬性可以動態的得到該元素的大小、滾動距離等。

scroll系列屬性:

三大系列總結

三大系列的內容包含:

主要用法如下:

offset系列 經常用於獲得元素位置 offsetLeft offsetTopclient經常用於獲取元素大小 clientWidth clientHeightscroll 經常用於獲取滾動距離 scrollTop scrollLeft 註意頁面滾動的距離通過 window.pageXOffset 獲得

看完這篇博客,是不是把放大鏡案例直接拿下!本案例不算難,主要是通過這個案例復習BOM對象中的offset、client和scroll。我們還可以通過這些知識點完成模態框的制作、消滅星星案例哦~

以上就是Javascript實例項目放大鏡特效的實現流程的詳細內容,更多關於Javascript 放大鏡特效的資料請關註WalkonNet其它相關文章!

推薦閱讀: