首頁 > 軟體

建立圖片對比slider滾軸範例詳解

2022-08-17 18:02:54

引言

在這篇文章, 我們會建立一個 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 滾軸,可以很清楚的看到圖片的對比效果。

下面我們就來看看是如何實現的。

定義 HTML 結構

<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%;
}

修改後的元素初始預設佔據 50% 的寬度。

我們不使用 img 元素來顯示修改後的圖片,而是使用背景圖方式顯示,因為圖片可以進行縮放。

<div
  class="modified-image"
  style="background-image: url('https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/361d53f154ec41668a661d1d927f0c2e~tplv-k3u1fbpfcp-watermark.image?')"
></div>

因為使用背景圖,所以修改後的圖片元素需要設定更多樣式,以達到最佳的顯示效果。

.modified-image {
  background-position: top left;
  background-repeat: no-repeat;
  background-size: auto 100%;
  /* ... */
}

為了達到對比的效果,我們還要給修改後的圖片新增一層濾鏡效果。

.modified-image {
  filter: grayscale(100%);
  /* ... */
}

接下來設定 .resizer 元素的樣式,相對而言要簡單很多,只需要將它設定到中心位置即可。

.resizer {
  position: absolute;
  left: 50%;
  top: 0;
  height: 100%;
  width: 2px;
  background-color: #cbd5e0;
  cursor: ew-resize;
}

使用 position 屬性將它定為到中間,注意將滑鼠的展現形式更換為 cursor: ew-resize

HTML 結構和 CSS 樣式就差不多了,接下來處理 JavaScript 事件相關內容。

當我們移動 .resizer 元素時,需要事實計算滑鼠移動了多遠的距離。然後根據當前滑鼠的位置,修改 .resizer 元素的位置,以及修改後圖片的大小。

如何拖動一個元素其實很簡單,還不是很清楚的同學可以去看看我之前的文章 《如何實現一個自定義的 range slider?元素拖動其實很簡單》

接下來來看看

實際程式碼

const resizer = document.getElementById('dragMe');
// 上一個兄弟元素,也就是修改後的圖片元素
const leftSide = resizer.previousElementSibling;
// 記錄當前滑鼠的位置
let x = 0;
let y = 0;
// 記錄修改後圖片的寬度
let leftWidth = 0;
// 點選 resizer 元素時觸發 mousedown 事件
const mouseDownHandler = function (e) {
  // 獲取當前滑鼠位置
  x = e.clientX;
  y = e.clientY;
  leftWidth = leftSide.getBoundingClientRect().width;
  // 在 document 元素上新增事件
  document.addEventListener('mousemove', mouseMoveHandler);
  document.addEventListener('mouseup', mouseUpHandler);
};
const mouseMoveHandler = function (e) {
  // 計算滑鼠移動距離
  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 元素新增事件
resizer.addEventListener('mousedown', mouseDownHandler);

程式碼有點長,需要你花點時間仔細看看才能理解。

最後還有一個需要注意的點,我們要保證滑鼠滾軸不會滑出可視範圍,所以需要限制其最大值和最小值。

因為修改後的圖片元素的寬度值時百分比型別,所以最小值為 0,最大值為 100。

const mouseMoveHandler = function (e) {
  // ...
  newLeftWidth = Math.max(newLeftWidth, 0);
  newLeftWidth = Math.min(newLeftWidth, 100);
};

以上就是建立圖片對比slider滾軸範例詳解的詳細內容,更多關於圖片對比slider滾軸的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com