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

图像滑块对比功能的开发记录

背景介绍

最近,公司需要开发一款在线图像压缩工具,其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此,我们设计了一个对比组件,它允许用户通过拖动滑块,动态调整两张图像的显示区域,从而清晰地看到压缩前后的差异。

目标效果

  • 两张图片堆叠放置,一张始终可见,另一张可调整可见范围。
  • 通过滑块拖动,控制上层图片的显示区域。
  • 适配 PC 和移动端,提供流畅的交互体验。

效果如图:

开发思路

结构设计

  1. 创建一个外层容器,用于包裹两张图片和滑块。
  2. 底层图片(原始图像)始终可见。
  3. 顶层图片(优化后图像)放置在上方,并使用 clip-path 控制其显示范围。
  4. 滑块(拖动条) 用于调整顶层图片的可见区域。
<div class="image-change-block"><div class="desc-container"><div class="before-desc">BEFORE (827 KB)</div><div class="after-desc">AFTER (94 KB)</div></div><img src="after.jpg" class="new-img" /><div class="clip-container"><img src="before.jpg" class="old-img" /></div><div class="handle-container"><div class="bar-btn" id="barBtn"></div><div class="bar-line" id="barLine"></div></div>
</div>

样式布局

  • 两张图片:底层图片 position: absolute; 覆盖整个容器,顶层图片使用 clip-path 或 width 控制显示区域。
  • 滑块样式:自定义 div + 伪元素 作为滑块,并放在 absolute 位置。
.image-change-block {position: relative;max-width: 44rem;overflow: hidden;border-radius: 1.25rem;
}.desc-container {top: 1.25rem;position: absolute;display: flex;align-items: center;justify-content: space-between;flex-wrap: wrap;width: 100%;padding: 0 1.25rem;gap: 0.3125rem;
}.after-desc,
.before-desc {background-color: #000000;opacity: 0.6;color: #fff;border-radius: 0.25rem;z-index: 10;font-size: var(--global--font-size-sm);padding: 0.3125rem 1.5rem;
}.old-img,
.new-img {width: 100%;height: 100%;object-fit: cover;display: block;
}.clip-container {position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;
}.old-img {position: absolute;top: 0;left: 0;width: 100%;height: 100%;clip-path: inset(0 50% 0 0);transition: clip-path 0.01s ease;
}.handle-container {position: absolute;top: 0;left: 0;height: 100%;width: 100%;pointer-events: none;
}.bar-btn {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width: 2rem;height: 2rem;border-radius: 50%;pointer-events: all;cursor: ew-resize;z-index: 2;
}.bar-line {position: absolute;top: 0;left: 50%;height: 100%;width: 3px;background-color: var(--theme-green-color);z-index: 1;
}.bar-btn::before {width: 28px;height: 28px;content: "";cursor: ew-resize;background: #00d4c9;position: absolute;left: 50%;top: 50%;transform: translate(-45%, -50%);display: block;border-radius: 50%;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);z-index: 1;
}.bar-btn::after {content: "";background: var(--theme-green-color);width: 3px;height: 100%;position: absolute;left: 50%;top: 0;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

交互逻辑

封装一个兼容 PC 和移动端的拖拽对比函数,通过传入对应的 dom 实现鼠标或手指拖动滑块时图像的对比。

initClip({barBtn: document.querySelector(`.bar-btn`),barLine: document.querySelector(`.bar-line`),clipContainer: document.querySelector(`.clip-container`),oldImg: document.querySelector(`.old-img`),
});/*** 初始化通过剪裁实现图像对比的功能* @param {Object} doms - 包含所需DOM元素的对象*  - barBtn: 滑动按钮元素*  - barLine: 滑动线条元素*  - clipContainer: 剪裁容器元素*  - oldImg: 被剪裁的图片元素*/
function initClip(doms) {// 解构赋值获取所需的DOM元素const { barBtn, barLine, clipContainer, oldImg } = doms;// 定义变量以跟踪鼠标或触摸是否在拖动let isDragging = false;let isMDragging = false;/*** 更新图片剪裁位置* @param {number} x - 鼠标或触摸在剪裁容器上的x坐标*/function updateImageClip(x) {// 计算剪裁容器的宽度const containerWidth = clipContainer.offsetWidth;// 计算并限制剪裁的百分比const percent = Math.min(Math.max(x / containerWidth, 0), 1);// 更新图片的剪裁路径oldImg.style.clipPath = `inset(0 ${100 - percent * 100}% 0 0)`;// 更新滑动按钮和线条的位置barBtn.style.left = `${percent * 100}%`;barLine.style.left = `${percent * 100}%`;}// 添加鼠标按下事件监听器到滑动按钮barBtn.addEventListener("mousedown", (e) => {// 开始拖动并阻止默认行为isDragging = true;e.preventDefault();});// 添加鼠标抬起事件监听器到文档document.addEventListener("mouseup", () => {// 结束拖动isDragging = false;});// 添加鼠标移动事件监听器到文档document.addEventListener("mousemove", (e) => {// 如果正在拖动,则更新图片剪裁if (isDragging) {const x = e.clientX - clipContainer.getBoundingClientRect().left;updateImageClip(x);}});// 添加点击事件监听器到剪裁容器clipContainer.addEventListener("click", (e) => {// 点击时更新图片剪裁const x = e.clientX - clipContainer.getBoundingClientRect().left;updateImageClip(x);});// 添加触摸开始事件监听器到滑动按钮barBtn.addEventListener("touchstart", (e) => {// 开始拖动并阻止默认行为isMDragging = true;e.preventDefault();});// 添加触摸结束事件监听器到文档document.addEventListener("touchend", () => {// 结束拖动isMDragging = false;});// 添加触摸移动事件监听器到文档document.addEventListener("touchmove", (e) => {// 如果正在拖动,则更新图片剪裁if (isMDragging) {const touch = e.touches[0];const x = touch.clientX - clipContainer.getBoundingClientRect().left;updateImageClip(x);}});
}

总结

这个滑块对比组件利用 clip-path 来裁剪图像,并结合鼠标和触摸事件监听,实现了流畅的交互体验。它不仅适用于图像压缩前后的对比,还可以扩展到滤镜效果、照片修复等其他图像对比场景。在实际开发中,我们可以根据 UI 需求,进一步优化滑块的样式、动画效果,以及提升移动端的操作体验。

原文链接

图像滑块对比功能的开发记录

相关文章:

图像滑块对比功能的开发记录

背景介绍 最近&#xff0c;公司需要开发一款在线图像压缩工具&#xff0c;其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此&#xff0c;我们设计了一个对比组件&#xff0c;它允许用户通过拖动滑块&#xff0c;动态调整两张图像的显示区域&#xff0c;从而清晰…...

【计算机网络】Socket

Socket 是网络通信的核心技术之一&#xff0c;充当应用程序与网络协议栈之间的接口。 1. Socket 定义 Socket&#xff08;套接字&#xff09;是操作系统提供的 网络通信抽象层&#xff0c;允许应用程序通过标准接口&#xff08;如 TCP/IP 或 UDP&#xff09;进行数据传输。它…...

Electron应用中获取设备唯一ID和系统信息

让我创建一篇关于如何在Electron应用中获取设备唯一ID和系统信息&#xff0c;并在登录时使用这些信息的博客文章。我将确保步骤明确、条理清晰&#xff0c;适合初学者和有经验的开发者。 这篇博客应包含以下部分&#xff1a; 介绍 - 为什么需要获取设备信息前提条件和安装依赖…...

文件上传漏洞:upload-labs靶场11-20

目录 pass-11 pass-12 pass-13 pass-14 pass-15 pass-16 pass-17 pass-18 pass-19 pass-20 pass-11 分析源代码 &#xff0c;发现上传文件的存放路径可控 if(isset($_POST[submit])){$ext_arr array(jpg,png,gif);$file_ext substr($_FILES[upload_file][name],st…...

国产化板卡设计原理图:2330-基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡

基于FMC接口的JFM7K325T PCIeX4 3U PXIe接口卡 一、板卡概述 本板卡基于 FPGAJFM7K325T 芯片&#xff0c;pin_to_pin兼容FPGAXC7K410T-2FFG900 &#xff0c;支持PCIeX8、64bit DDR3容量2GByte&#xff0c;HPC的FMC连接器&#xff0c;板卡支持PXIE标准协议&#xff0c;其中XJ3…...

使用Open WebUI下载的模型文件(Model)默认存放在哪里?

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Ollama部署LLM专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年2月21日21点21分 &#x1f004;️文章质量&#xff1a;95分 文章目录 使用CMD安装存放位置 默认存放路径 Open WebUI下…...

FPGA 配置原理

用户编程控制的FPGA 是通过加载比特位流配置内部的存储单元实现的。该存储单元就是所谓的配置单元&#xff0c;它必须在器件上电后进行配置&#xff0c;从而设置查找表&#xff08;LUT&#xff09;的属性、连线方式、IOB 电压标准和其它的用户设计。 1.配置帧 以Xilinx 公司的…...

企业级虚拟化数据库基础平台自动化部署项目

一、项目简介及准备工作 1.1.虚拟化平台简介 1.1.1.ESXi 8 是什么&#xff1f; 定义&#xff1a; ESXi 8 是 VMware 推出的最新版本 裸机虚拟化管理程序&#xff08;Hypervisor&#xff09;&#xff0c;属于 VMware vSphere 产品线的核心组件。 核心功能&#xff1a; 在物理…...

关于elementui的时间组件与后端时间和oracle数据库时间的对应格式

前端&#xff1a; <el-date-pickerv-model"formInline.startTime"type"date"value-format"yyyy-MM-dd"placeholder"选择日期"> </el-date-picker> 后端&#xff1a; private String startTime; private String endTime…...

一周学会Flask3 Python Web开发-WTForms表单验证

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们可以通过WTForms表单类属性的validators属性来实现表单验证。 常用的WTForms验证器 验证器说明DataRequired(messageNo…...

qt open3dBPA重建

qt open3dBPA重建 效果展示二、流程三、代码效果展示 二、流程 创建动作,链接到槽函数,并把动作放置菜单栏 参照前文 三、代码 1、槽函数实现 void on_actionBPA_triggered();//bpa重建 void MainWindow::...

Unity游戏开发中的网格简化与LOD技术(Mesh Simplification LOD)

在Unity游戏开发中&#xff0c;网格简化&#xff08;Mesh Simplification&#xff09;和LOD&#xff08;Level of Detail&#xff09;技术是优化渲染性能的关键手段&#xff0c;尤其在处理复杂场景和高精度模型时至关重要。以下是一套系统的实现方案与优化策略&#xff1a; 一、…...

基于YOLO11深度学习的运动品牌LOGO检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

纯html文件实现目录和文档关联

目录结构 效果图 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>项目结题报告</title><style lang"scss">::-webkit-scrollbar {width: 6px;height: 6px;}::-webkit-scro…...

C# | 委托 | 事件 | 异步

委托&#xff08;Delegate&#xff09;和事件&#xff08;Event&#xff09; 在C#和C中&#xff0c;委托&#xff08;Delegate&#xff09;与事件&#xff08;Event&#xff09;以及函数对象&#xff08;Function Object&#xff09;是实现回调机制或传递行为的重要工具。虽然…...

数据结构——顺序表与链表

1. 基础介绍 1、线性结构&#xff1a; 如果一个数据元素序列满足&#xff1a; &#xff08;1&#xff09;除第一个和最后一个数据元素外&#xff0c;每个数据元素只有一个前驱数据元素和一个后继数据元素&#xff1b; &#xff08;2&#xff09;第一个数据元素没有前驱数据…...

【uniapp】图片添加canvas水印

目录 需求&背景实现地理位置添加水印 ios补充 需求&背景 需求&#xff1a;拍照后给图片添加水印, 水印包含经纬度、用户信息、公司logo等信息。 效果图&#xff1a; 方案&#xff1a;使用canvas添加水印。 具体实现&#xff1a;上传图片组件是项目里现有的&#xff…...

ElementUI 级联选择器el-cascader启用选择任意一级选项,选中后关闭下拉框

1、启用选择任意一级选项 在 el-cascader 标签上加上配置项&#xff1a; :props"{ checkStrictly: true }"例如&#xff1a; <el-cascaderref"selectedArrRef"v-model"selectedArr":options"optionsList":props"{ checkStri…...

【音视频】ffplay常用命令

一、 ffplay常用命令 -x width&#xff1a;强制显示宽度-y height&#xff1a;强制显示高度 强制以 640*360的宽高显示 ffplay 2.mp4 -x 640 -y 360 效果如下 -fs 全屏显示 ffplay -fs 2.mp4效果如下&#xff1a; -an 禁用音频&#xff08;不播放声音&#xff09;-vn 禁…...

5人3小时复刻Manus?开源OpenManus项目全解剖,我的DeepSeek股票报告这样诞生

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。分享AI算法干货、技术心得。 更多文章可关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! OpenManus是什么 1. 项目背景 OpenManus 是由 MetaGPT 核心团队仅用 3 小时复刻而成的开源…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...