
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图片拖动Clip对比功能</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {font-family: Arial, sans-serif;background-color: #f0f0f0;display: flex;justify-content: center;align-items: center;min-height: 100vh;padding: 20px;}.container {max-width: 800px;width: 100%;height: 500px;border-radius: 12px;overflow: hidden;background-color: white;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);border: 1px solid #e0e0e0;}.image-comparison {position: relative;height: 100%;width: 100%;display: flex;overflow: hidden;touch-action: none;user-select: none;}.image-comparison img {display: block;width: 100%;height: 100%;object-fit: cover;object-position: center center;}.clip-item {position: absolute;top: 0;left: 0;width: 100%;height: 100%;user-select: none;will-change: clip-path;clip-path: inset(0 0 0 50%);transition: clip-path 0.1s ease-out;}.handle-container {position: absolute;top: 0;height: 100%;background: none;border: 0;padding: 0;pointer-events: all;appearance: none;outline: 0;transform: translate3d(-50%, 0, 0);left: 50%;cursor: ew-resize;z-index: 10;}.handle-root {display: flex;flex-direction: column;place-items: center;height: 100%;cursor: ew-resize;pointer-events: none;color: white;}.handle-line {flex-grow: 1;height: 100%;width: 2px;background-color: currentColor;pointer-events: auto;box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);}.handle-button {display: grid;grid-auto-flow: column;gap: 8px;place-content: center;flex-shrink: 0;width: 56px;height: 56px;border-radius: 50%;border: 2px solid currentColor;pointer-events: auto;backdrop-filter: blur(7px);background-color: rgba(0, 0, 0, 0.125);box-shadow: 0 0 4px rgba(0, 0, 0, 0.35);}.handle-arrow {width: 0;height: 0;border-top: 8px solid transparent;border-right: 10px solid currentColor;border-bottom: 8px solid transparent;}.handle-arrow:last-child {transform: rotate(180deg);}.info {position: absolute;bottom: 20px;left: 20px;background: rgba(0, 0, 0, 0.7);color: white;padding: 10px 15px;border-radius: 8px;font-size: 14px;z-index: 5;}@media (max-width: 768px) {.container {height: 400px;}.handle-button {width: 48px;height: 48px;}}</style>
</head>
<body><div class="container"><div class="image-comparison" id="imageComparison"><img alt="Original Image" src="./img/demo5.png"><div class="clip-item" id="clipItem"><img alt="Translated Image" src="./img/demo6.png"></div><button class="handle-container" id="handleContainer" aria-label="拖动移动或聚焦并使用箭头键" aria-orientation="horizontal" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50" role="slider"><div class="handle-root"><div class="handle-line"></div><div class="handle-button"><div class="handle-arrow"></div><div class="handle-arrow"></div></div><div class="handle-line"></div></div></button><div class="info">拖动中间的滑块来对比两张图片</div></div></div><script>class ImageComparison {constructor(container) {this.container = container;this.clipItem = container.querySelector('#clipItem');this.handleContainer = container.querySelector('#handleContainer');this.isDragging = false;this.currentPosition = 50; this.init();}init() {this.bindEvents();this.updatePosition(this.currentPosition);}bindEvents() {this.handleContainer.addEventListener('mousedown', this.handleMouseDown.bind(this));document.addEventListener('mousemove', this.handleMouseMove.bind(this));document.addEventListener('mouseup', this.handleMouseUp.bind(this));this.handleContainer.addEventListener('touchstart', this.handleTouchStart.bind(this));document.addEventListener('touchmove', this.handleTouchMove.bind(this));document.addEventListener('touchend', this.handleTouchEnd.bind(this));this.handleContainer.addEventListener('keydown', this.handleKeyDown.bind(this));this.container.addEventListener('selectstart', (e) => e.preventDefault());}handleMouseDown(e) {e.preventDefault();this.isDragging = true;this.container.style.cursor = 'ew-resize';this.clipItem.style.transition = 'none';}handleMouseMove(e) {if (!this.isDragging) return;e.preventDefault();const rect = this.container.getBoundingClientRect();const x = e.clientX - rect.left;const percentage = (x / rect.width) * 100;this.updatePosition(Math.max(0, Math.min(100, percentage)));}handleMouseUp() {this.isDragging = false;this.container.style.cursor = '';this.clipItem.style.transition = 'clip-path 0.1s ease-out';}handleTouchStart(e) {e.preventDefault();this.isDragging = true;this.clipItem.style.transition = 'none';}handleTouchMove(e) {if (!this.isDragging) return;e.preventDefault();const touch = e.touches[0];const rect = this.container.getBoundingClientRect();const x = touch.clientX - rect.left;const percentage = (x / rect.width) * 100;this.updatePosition(Math.max(0, Math.min(100, percentage)));}handleTouchEnd() {this.isDragging = false;this.clipItem.style.transition = 'clip-path 0.1s ease-out';}handleKeyDown(e) {const step = 5;switch(e.key) {case 'ArrowLeft':e.preventDefault();this.updatePosition(Math.max(0, this.currentPosition - step));break;case 'ArrowRight':e.preventDefault();this.updatePosition(Math.min(100, this.currentPosition + step));break;case 'Home':e.preventDefault();this.updatePosition(0);break;case 'End':e.preventDefault();this.updatePosition(100);break;}}updatePosition(percentage) {this.currentPosition = percentage;this.clipItem.style.clipPath = `inset(0 0 0 ${percentage}%)`;this.handleContainer.style.left = `${percentage}%`;this.handleContainer.setAttribute('aria-valuenow', Math.round(percentage));}}document.addEventListener('DOMContentLoaded', () => {const container = document.getElementById('imageComparison');new ImageComparison(container);});</script>
</body>
</html>