創(chuàng)建圖片對比slider滑塊示例詳解
引言

在這篇文章, 我們會創(chuàng)建一個 slider 滑塊來對比兩張圖片。
老樣子,話不多說,先看效果。

CSS
.container {
position: relative;
}
.resizer {
background-color: #cbd5e0;
cursor: ew-resize;
height: 100%;
left: 50%;
position: absolute;
top: 0;
width: 2px;
}
.modified-image {
background-position: top left;
background-repeat: no-repeat;
background-size: auto 100%;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 50%;
filter: grayscale(100%);
}JavaScript
// Query the element
const resizer = document.getElementById('dragMe');
const leftSide = resizer.previousElementSibling;
const rightSide = resizer.nextElementSibling;
// The current position of mouse
let x = 0;
let y = 0;
let leftWidth = 0;
// Handle the mousedown event
// that's triggered when user drags the resizer
const mouseDownHandler = function (e) {
// Get the current mouse position
x = e.clientX;
y = e.clientY;
leftWidth = leftSide.getBoundingClientRect().width;
// Attach the listeners to `document`
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
};
const mouseMoveHandler = function (e) {
// How far the mouse has been moved
const dx = e.clientX - x;
const dy = e.clientY - y;
let newLeftWidth =
((leftWidth + dx) * 100) / resizer.parentNode.getBoundingClientRect().width;
newLeftWidth = Math.max(newLeftWidth, 0);
newLeftWidth = Math.min(newLeftWidth, 100);
leftSide.style.width = `${newLeftWidth}%`;
resizer.style.left = `${newLeftWidth}%`;
resizer.style.cursor = 'col-resize';
resizer.parentNode.style.cursor = 'col-resize';
leftSide.style.userSelect = 'none';
leftSide.style.pointerEvents = 'none';
rightSide.style.userSelect = 'none';
rightSide.style.pointerEvents = 'none';
};
const mouseUpHandler = function () {
resizer.style.removeProperty('cursor');
resizer.parentNode.style.removeProperty('cursor');
leftSide.style.removeProperty('user-select');
leftSide.style.removeProperty('pointer-events');
rightSide.style.removeProperty('user-select');
rightSide.style.removeProperty('pointer-events');
// Remove the handlers of `mousemove` and `mouseup`
document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
};
// Attach the handler
resizer.addEventListener('mousedown', mouseDownHandler);通過上面的示例可以看到,拖動中間的 slider 滑塊,可以很清楚的看到圖片的對比效果。
下面我們就來看看是如何實(shí)現(xiàn)的。
定義 HTML 結(jié)構(gòu)
<div class="container">
<!-- 修改后的圖 -->
<div class="modified-image"></div>
<!-- slider 滑塊 -->
<div class="resizer" id="dragMe"></div>
<!-- 原圖 -->
<img
src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/361d53f154ec41668a661d1d927f0c2e~tplv-k3u1fbpfcp-watermark.image?"
/>
</div>
修改后的圖放在底部,滑塊在中間,原圖在最上層。
定義 CSS 樣式
.container {
position: relative;
}
.modified-image {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 50%;
}
修改后的元素初始默認(rèn)占據(jù) 50% 的寬度。
我們不使用 img 元素來顯示修改后的圖片,而是使用背景圖方式顯示,因?yàn)閳D片可以進(jìn)行縮放。
<div
class="modified-image"
style="background-image: url('https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/361d53f154ec41668a661d1d927f0c2e~tplv-k3u1fbpfcp-watermark.image?')"
></div>
因?yàn)槭褂帽尘皥D,所以修改后的圖片元素需要設(shè)置更多樣式,以達(dá)到最佳的顯示效果。
.modified-image {
background-position: top left;
background-repeat: no-repeat;
background-size: auto 100%;
/* ... */
}
為了達(dá)到對比的效果,我們還要給修改后的圖片添加一層濾鏡效果。
.modified-image {
filter: grayscale(100%);
/* ... */
}
接下來設(shè)置 .resizer 元素的樣式,相對而言要簡單很多,只需要將它設(shè)置到中心位置即可。
.resizer {
position: absolute;
left: 50%;
top: 0;
height: 100%;
width: 2px;
background-color: #cbd5e0;
cursor: ew-resize;
}
使用 position 屬性將它定為到中間,注意將鼠標(biāo)的展現(xiàn)形式更換為 cursor: ew-resize。
HTML 結(jié)構(gòu)和 CSS 樣式就差不多了,接下來處理 JavaScript 事件相關(guān)內(nèi)容。
當(dāng)我們移動 .resizer 元素時,需要事實(shí)計(jì)算鼠標(biāo)移動了多遠(yuǎn)的距離。然后根據(jù)當(dāng)前鼠標(biāo)的位置,修改 .resizer 元素的位置,以及修改后圖片的大小。
如何拖動一個元素其實(shí)很簡單,還不是很清楚的同學(xué)可以去看看我之前的文章 《如何實(shí)現(xiàn)一個自定義的 range slider?元素拖動其實(shí)很簡單》。
接下來來看看
實(shí)際代碼
const resizer = document.getElementById('dragMe');
// 上一個兄弟元素,也就是修改后的圖片元素
const leftSide = resizer.previousElementSibling;
// 記錄當(dāng)前鼠標(biāo)的位置
let x = 0;
let y = 0;
// 記錄修改后圖片的寬度
let leftWidth = 0;
// 點(diǎn)擊 resizer 元素時觸發(fā) mousedown 事件
const mouseDownHandler = function (e) {
// 獲取當(dāng)前鼠標(biāo)位置
x = e.clientX;
y = e.clientY;
leftWidth = leftSide.getBoundingClientRect().width;
// 在 document 元素上添加事件
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
};
const mouseMoveHandler = function (e) {
// 計(jì)算鼠標(biāo)移動距離
const dx = e.clientX - x;
const dy = e.clientY - y;
let newLeftWidth =
((leftWidth + dx) * 100) / resizer.parentNode.getBoundingClientRect().width;
newLeftWidth = Math.max(newLeftWidth, 0);
newLeftWidth = Math.min(newLeftWidth, 100);
// 設(shè)置修改后的圖片元素的寬度
leftSide.style.width = `${newLeftWidth}%`;
resizer.style.left = `${newLeftWidth}%`;
};
// 給 resizer 元素添加事件
resizer.addEventListener('mousedown', mouseDownHandler);
代碼有點(diǎn)長,需要你花點(diǎn)時間仔細(xì)看看才能理解。
最后還有一個需要注意的點(diǎn),我們要保證鼠標(biāo)滑塊不會滑出可視范圍,所以需要限制其最大值和最小值。
因?yàn)樾薷暮蟮膱D片元素的寬度值時百分比類型,所以最小值為 0,最大值為 100。
const mouseMoveHandler = function (e) {
// ...
newLeftWidth = Math.max(newLeftWidth, 0);
newLeftWidth = Math.min(newLeftWidth, 100);
};以上就是創(chuàng)建圖片對比slider滑塊示例詳解的詳細(xì)內(nèi)容,更多關(guān)于圖片對比slider滑塊的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
前端算法leetcode109題解有序鏈表轉(zhuǎn)換二叉搜索樹
一篇文章教你學(xué)會js實(shí)現(xiàn)彈幕效果
微信小程序中使元素占滿整個屏幕高度實(shí)現(xiàn)方法
微信小程序 頁面跳轉(zhuǎn)和數(shù)據(jù)傳遞實(shí)例詳解
微信小程序 圖片加載(本地,網(wǎng)路)實(shí)例詳解

