企业网站怎么注册官网,十堰网站建设专家,东莞网络推广建站,织梦只显示网站首页背景介绍
最近#xff0c;公司需要开发一款在线图像压缩工具#xff0c;其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此#xff0c;我们设计了一个对比组件#xff0c;它允许用户通过拖动滑块#xff0c;动态调整两张图像的显示区域#xff0c;从而清晰…背景介绍
最近公司需要开发一款在线图像压缩工具其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此我们设计了一个对比组件它允许用户通过拖动滑块动态调整两张图像的显示区域从而清晰地看到压缩前后的差异。
目标效果
两张图片堆叠放置一张始终可见另一张可调整可见范围。通过滑块拖动控制上层图片的显示区域。适配 PC 和移动端提供流畅的交互体验。
效果如图 开发思路
结构设计
创建一个外层容器用于包裹两张图片和滑块。底层图片原始图像始终可见。顶层图片优化后图像放置在上方并使用 clip-path 控制其显示范围。滑块拖动条 用于调整顶层图片的可见区域。
div classimage-change-blockdiv classdesc-containerdiv classbefore-descBEFORE (827 KB)/divdiv classafter-descAFTER (94 KB)/div/divimg srcafter.jpg classnew-img /div classclip-containerimg srcbefore.jpg classold-img //divdiv classhandle-containerdiv classbar-btn idbarBtn/divdiv classbar-line idbarLine/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 需求进一步优化滑块的样式、动画效果以及提升移动端的操作体验。
原文链接
图像滑块对比功能的开发记录