当前位置: 首页 > news >正文

两张图片对比clip功能

在这里插入图片描述

<!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; // 初始位置 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;// 更新clip-paththis.clipItem.style.clipPath = `inset(0 0 0 ${percentage}%)`;// 更新滑块位置this.handleContainer.style.left = `${percentage}%`;// 更新ARIA属性this.handleContainer.setAttribute('aria-valuenow', Math.round(percentage));}}// 初始化document.addEventListener('DOMContentLoaded', () => {const container = document.getElementById('imageComparison');new ImageComparison(container);});</script>
</body>
</html>
http://www.lryc.cn/news/583107.html

相关文章:

  • 在 PyCharm 中安装并配置 Node.js 的指南
  • 整合Spring、Spring MVC与MyBatis:构建高效Java Web应用
  • Linux的 `test`命令(或等价中括号写法 `[空格expression空格]`)的用法详解. 笔记250709
  • 自制明信片DIY:让心意更有温度
  • python Gui界面小白入门学习
  • OpenCV图像增强秘籍:高通滤波与特效艺术
  • 学习open62541 --- [79] 在docker中运行open62541工程
  • SpringCloud系列 - xxl-job 分布式任务调度 (七)
  • Docker高级管理
  • Wireshark抓包实验之TCP连接
  • 使用 Docker Compose 简化 INFINI Console 与 Easysearch 环境搭建
  • 数据管理新范式:基于Docker的私有云存储系统构建指南
  • 7.9 note| dfs
  • 【Linux】Rocky Linux 安装 Docker 与 Docker-Compose
  • 【vLLM 学习】Eagle
  • 多代理混战?用 PAC(Proxy Auto-Config) 优雅切换代理场景
  • 选哪个数据恢复软件?六款深度数据恢复软件介绍
  • 数据基础练习
  • 【Linux】权限的概念及理解
  • 进程于线程-3
  • 代码审计-springel表达式注入
  • JSP动态网页开发基础
  • 前后端集合如何传递
  • 主流大模型Agent框架 AutoGPT详解
  • thinkphp使用redis抢单实例
  • 如何将华为手机中的照片传输到电脑
  • 超越公有云:在裸金属服务器上构建低成本、高性能的静态资源服务
  • 【RK3568+PG2L50H开发板实验例程】FPGA部分 | Pango 的时钟资源——锁相环
  • 川翔云电脑:突破硬件极限,重构设计生产力范式
  • 使用DDR4控制器实现多通道数据读写(十九)