最近看到一篇講放大鏡的文章,實踐后感覺效果非常好,這里分享給大家,
效果如下:

其實作核心:
CSS函式,如:calc() —— 動態計算;var() —— 使用自定義變數 CSS偽元素:::before/after —— 方便控制,而且獨立于檔案流之外,易于渲染 JS API:offsetX/offsetY:相對父節點區域左上角定位
其實我們具體要實作的就是:在滑鼠移入時顯示出來一個小圓圈(跟著滑鼠走),這個小圓圈到哪,哪里的圖片區域就放大相應的倍數并且顯示在圓圈內,
為什么要用offset API? 其實根據上面的描述,我們需要實時獲取滑鼠的左偏移量和上偏移量,而這兩個偏移量是相對父節點的,通過左偏移量和上偏移量結合calc()即可計算放大鏡顯示內容相對父節點的顯示位置, 不難找到在滑鼠事件物件中,js為我們提供了如下API: screenX/screenY:相對螢屏區域左上角定位,若發生滾動行為,則相對該區域定位 pageX/pageY:相對網頁區域左上角定位 clientX/clientY:相對瀏覽器可視區域左上角定位 offsetX/offsetY:相對父節點區域左上角定位,若無父節點則相對<html>或<body>定位 但相較而言唯一符合要求的就只有offset“相對于父元素”了,
代碼如下:
<div >
<div ></div>
</div>
let magnifier=document.querySelector(".magnifier");
magnifier.addEventListener("mousemove",e=>{
//控制“鏡子”小圓圈的移動
});
放大鏡顯示內容其實就是將原影像放大N倍,通過上述偏移量按照比例截取一定區域顯示內容,
先定義相關的css變數,我們設定放大倍率為2.5倍,那么被放大影像的寬高也是原來寬高的2.5倍,宣告兩個變數,分為為 --x 和 --y :
:root{
--ratio: 2.5;
--box-w: 600px;
--box-h: 400px;
--outbox-w: calc(var(--box-w) * var(--ratio));
--outbox-h: calc(var(--box-h) * var(--ratio));
}
.bruce{
margin-top: 50px;
}
.magnifier{
--x:0;
--y:0;
overflow: hidden;
position: relative;
width: var(--box-w);
height: var(--box-h);
background: url("img/nan.png") no-repeat center/100% 100%;
cursor: grabbing;
}
圖片以背景圖的形式展示,方便控制大小,
很顯然在這個場景下無需插入子節點作為放大鏡的容器了,使用::before即可!
放大鏡在使用時寬高為100px,不使用時寬高為0,通過絕對定位布局放大鏡隨滑鼠移動的位置,即宣告left和top,再通過宣告 transform:translate(-50%,-50%) 將放大鏡補位,使放大鏡中心與滑鼠游標位置一致,由于宣告left和top定位放大鏡的位置,還可以宣告 will-change 改善left和top因改變而引發的性能問題!
而且用CSS解決這些問題的另一個好處就是:借助于偽元素/偽類,我們可以將一些比較細節的東西用CSS解決,而不是寄托于“繁重”的JavaScript,比如:滑鼠移入樣式hover:
.magnifier::before{
--size: 0;
position: absolute;
left: var(--x);
top: var(--y);
border-radius: 100%;
width: var(--size);
height: var(--size);
box-shadow: 1px 1px 3px rgba(0,0,0,.5);
content: "";
will-change: left,top;
transform: translate(-50%,-50%);
}
.magnifier:hover::before{
--size: 100px;
}
接下來使用background實作(展示)放大鏡內容,依據放大倍率為2.5倍,那么可宣告size: --outbox-w --outbox-h,通過 position-x 和 position-y 移動背景即可,最終可連寫成 background:#333 url(背景圖片) no-repeat var(--scale-x) var(--scale-y)/var(--outbox-w) var(--outbox-h) ,
其中 --scale-x 和 --scale-y 對應 position-x 和 position-y (即background-position),用于隨著滑鼠移動而改變背景位置,
--scale-x: calc(var(--size) / var(--ratio) - var(--ratio) * var(--x)); --scale-y: calc(var(--size) / var(--ratio) - var(--ratio) * var(--y));
那么上面mousemove函式中改變鏡子的“位置坐標”就可以這么寫了:
e.target.style.setProperty("--x",`${e.offsetX}px`);
e.target.style.setProperty("--y",`${e.offsetY}px`);
so eazy~
最終的CSS內容如下:
:root{
--ratio: 2.5;
--box-w: 600px;
--box-h: 400px;
--outbox-w: calc(var(--box-w) * var(--ratio));
--outbox-h: calc(var(--box-h) * var(--ratio));
}
.bruce{
margin-top: 50px;
}
.magnifier{
--x:0;
--y:0;
overflow: hidden;
position: relative;
width: var(--box-w);
height: var(--box-h);
background: url("img/nan.png") no-repeat center/100% 100%;
cursor: grabbing;
}
.magnifier::before{
--size: 0;
--scale-x: calc(var(--size) / var(--ratio) - var(--ratio) * var(--x));
--scale-y: calc(var(--size) / var(--ratio) - var(--ratio) * var(--y));
position: absolute;
left: var(--x);
top: var(--y);
border-radius: 100%;
width: var(--size);
height: var(--size);
background: #333 url("img/nan.png") no-repeat var(--scale-x) var(--scale-y)/var(--outbox-w) var(--outbox-h);
box-shadow: 1px 1px 3px rgba(0,0,0,.5);
content: "";
will-change: left,top;
transform: translate(-50%,-50%);
}
.magnifier:hover::before{
--size: 100px;
}
若是::before中想要用一張本身就是2倍大小的圖片,則background中將--outbox-w和--outbox-h替換為原本的--box-w和--box-h 再做適當的微調即可,
! 注意看你放大鏡中的內容,它表明不只是簡單的圖片的放大,所以才有了 var(--size) / var(--ratio) 這一段代碼; 關于css中修改css3自定義變數:我仍然認為只能在“同級同屬”范圍內才能修改并顯示成功,
轉載于:https://blog.csdn.net/qq_43624878/article/details/110197749
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/228871.html
標籤:JavaScript
上一篇:原生JS拖拽
下一篇:ng9新特性 lvy出場
