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

图片叠加拖拽对比展示效果实现——Vue版

图片叠加拖拽对比展示效果实现——Vue版

项目中遇见一个需求:2张图片按竖线分割,左右两侧分别展示对应图片,通过滚动条拖动对应展示图片区域;;
网上搜索了下,没有找到直接可用的组件,这里自己封装了一个次功能组件;后面会附上完整代码。,希望可以帮助到由此需求的小伙伴;

文章目录

  • 图片叠加拖拽对比展示效果实现——Vue版
    • 一、实现效果预览
    • 二、HTML 部分
      • 1. 组件包含:头部插槽、底部插槽、切换比较图片组
      • 2. 代码示例
    • 三、JS 部分
      • 1. 包含组件传参,左侧图片地址、右侧图片地址、事件处理等
      • 2. JS 部分代码如下:
    • 四、 CSS 样式代码
    • 六、完整使用示例

一、实现效果预览

在这里插入图片描述

二、HTML 部分

1. 组件包含:头部插槽、底部插槽、切换比较图片组

2. 代码示例

<template><div class="image-comparator"><!--  头部插槽  --><slot name="header"></slot><!--   切换对比图片  下一组、上一组 --><div class="prev" @click="prevFun"><i class="el-icon-arrow-left"></i></div><div class="next" @click="nextFun"><i class="el-icon-arrow-right"></i></div><!-- 核心标签代码   --><div class="container" @mouseenter="startDrag" @mousemove="onDrag" @mouseup="endDrag" @mouseleave="endDrag"><div class="image-wrapper":style="{ clipPath: `inset(0 ${100 - (dividerPosition / containerWidth * 100)}% 0 0)` }"><img src="https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg" class="image"/></div><div class="divider" :style="{ left: `${dividerPosition}px` }"></div><div class="image-wrapper" :style="{ clipPath: `inset(0 0 0 ${(dividerPosition / containerWidth * 100)}%)` }"><img src="https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg" class="image"/></div></div><!--  底部插槽  --><slot name="footer"></slot></div>
</template>

三、JS 部分

1. 包含组件传参,左侧图片地址、右侧图片地址、事件处理等

2. JS 部分代码如下:

<script>export default {name: 'imageComparator',props: {leftImgUrl: {type: String,},rightImgUrl: {type: String,},},data() {return {containerWidth: 500,dividerPosition: 250,dragging: false,containerRect: null,};},methods: {updateContainerWidth() {this.containerWidth = this.$el.querySelector('.container').clientWidth;},startDrag(event) {this.dragging = true;this.containerRect = this.$el.querySelector('.container').getBoundingClientRect();},onDrag(event) {if (this.dragging && this.containerRect) {let newPosition = event.clientX - this.containerRect.left;if (newPosition < 0) newPosition = 0;if (newPosition > this.containerRect.width) newPosition = this.containerRect.width;this.dividerPosition = newPosition;}},endDrag() {this.dragging = false;this.containerRect = null;},prevFun() {this.$emit('prevFun');},nextFun() {this.$emit('nextFun');},},mounted() {this.updateContainerWidth();window.addEventListener('resize', this.updateContainerWidth);},beforeDestroy() {window.removeEventListener('resize', this.updateContainerWidth);},};</script>

四、 CSS 样式代码

<style scoped lang="less">
.image-comparator {width: 90%;/*max-width: 600px;*/margin: 0 auto;.container {position: relative;width: 100%;height: 600px;overflow: hidden;}.image-wrapper {position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;}.image {width: 100%;height: 100%;object-fit: cover;}.divider {position: absolute;top: 0;bottom: 0;width: 2px;background-color: black;cursor: ew-resize;z-index: 10;}.prev, .next {position: absolute;top: 50%;transform: translateY(-50%);z-index: 100;cursor: pointer;font-size: 40px;color: white;background-color: rgba(0, 0, 0, 0.5);padding: 10px;border-radius: 50%;transition: all 0.3s ease;left: 10px;&:hover {background-color: rgba(0, 0, 0, 0.8);color: #0bf4cb;}&.next {right: 10px;left: auto;}}
}</style>

## 五、总结

本文着重介绍了Vue2 封装的图片分割展示组件,如果小伙伴项目是V3 可以自行修改Vue 组件即可,还有写组件传参地方,需要的话自行改为动态参数即可,这里父组件不做过多介绍,以免浪费小伙伴看代码时间;

六、完整使用示例

以下是一个完整的 代码示例

<template><div class="image-comparator"><!--  头部插槽  --><slot name="header"></slot><!--   切换对比图片  下一组、上一组 --><div class="prev" @click="prevFun"><i class="el-icon-arrow-left"></i></div><div class="next" @click="nextFun"><i class="el-icon-arrow-right"></i></div><!-- 核心标签代码   --><div class="container" @mouseenter="startDrag" @mousemove="onDrag" @mouseup="endDrag" @mouseleave="endDrag"><div class="image-wrapper":style="{ clipPath: `inset(0 ${100 - (dividerPosition / containerWidth * 100)}% 0 0)` }"><img src="https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg" class="image"/></div><div class="divider" :style="{ left: `${dividerPosition}px` }"></div><div class="image-wrapper" :style="{ clipPath: `inset(0 0 0 ${(dividerPosition / containerWidth * 100)}%)` }"><img src="https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg" class="image"/></div></div><!--  底部插槽  --><slot name="footer"></slot></div>
</template><script>
export default {name: 'imageComparator',props: {leftImgUrl: {type: String,},rightImgUrl: {type: String,},},data() {return {containerWidth: 500,dividerPosition: 250,dragging: false,containerRect: null,};},methods: {updateContainerWidth() {this.containerWidth = this.$el.querySelector('.container').clientWidth;},startDrag(event) {this.dragging = true;this.containerRect = this.$el.querySelector('.container').getBoundingClientRect();},onDrag(event) {if (this.dragging && this.containerRect) {let newPosition = event.clientX - this.containerRect.left;if (newPosition < 0) newPosition = 0;if (newPosition > this.containerRect.width) newPosition = this.containerRect.width;this.dividerPosition = newPosition;}},endDrag() {this.dragging = false;this.containerRect = null;},prevFun() {this.$emit('prevFun');},nextFun() {this.$emit('nextFun');},},mounted() {this.updateContainerWidth();window.addEventListener('resize', this.updateContainerWidth);},beforeDestroy() {window.removeEventListener('resize', this.updateContainerWidth);},};
</script>
<style scoped lang="less">
.image-comparator {width: 90%;/*max-width: 600px;*/margin: 0 auto;.container {position: relative;width: 100%;height: 600px;overflow: hidden;}.image-wrapper {position: absolute;top: 0;left: 0;width: 100%;height: 100%;overflow: hidden;}.image {width: 100%;height: 100%;object-fit: cover;}.divider {position: absolute;top: 0;bottom: 0;width: 2px;background-color: black;cursor: ew-resize;z-index: 10;}.prev, .next {position: absolute;top: 50%;transform: translateY(-50%);z-index: 100;cursor: pointer;font-size: 40px;color: white;background-color: rgba(0, 0, 0, 0.5);padding: 10px;border-radius: 50%;transition: all 0.3s ease;left: 10px;&:hover {background-color: rgba(0, 0, 0, 0.8);color: #0bf4cb;}&.next {right: 10px;left: auto;}}
}</style>

看到这里的小伙伴,欢迎点赞、评论,收藏!

如有前端相关疑问,请评论区留言,博主会在第一时间解答!!!

相关文章:

图片叠加拖拽对比展示效果实现——Vue版

图片叠加拖拽对比展示效果实现——Vue版 项目中遇见一个需求&#xff1a;2张图片按竖线分割&#xff0c;左右两侧分别展示对应图片&#xff0c;通过滚动条拖动对应展示图片区域&#xff1b;; 网上搜索了下&#xff0c;没有找到直接可用的组件&#xff0c;这里自己封装了一个次功…...

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中的应用前景

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中具有广泛的应用前景。如有滤波、导航方面的代码定制需求,可通过文末卡片联系作者获得帮助 文章目录 结合LSTM和UKF的背景结合LSTM和UKF的优势应用实例研究现状MATLAB代码示例结论结合LSTM和…...

【MATLAB APP Designer】小波阈值去噪(第一期)

代码原理及流程 小波阈值去噪是一种信号处理方法&#xff0c;用于从信号中去除噪声。这种方法基于小波变换&#xff0c;它通过将信号分解到不同的尺度和频率上来实现。其基本原理可以分为以下几个步骤&#xff1a; &#xff08;1&#xff09;小波变换&#xff1a;首先对含噪信…...

ClickHouse副本搭建

一. 副本概述 副本的目的主要是保障数据的高可用性&#xff0c;ClickHouse中的副本没有主从之分。所有的副本都是平等的。 副本写入流程&#xff1a; 二. 副本搭建 1. 实验环境 hadoop1(192.168.47.128) hadoop2(192.168.47.129)2. 修改配置文件 修改两台主机/etc/click…...

K3知识点

提示&#xff1a;文章 文章目录 前言一、顺序队列和链式队列题目 顺序队列和链式队列的定义和特性实际应用场景顺序表题目 链式队列 二、AVL树三、红黑树四、二叉排序树五、树的概念题目1左子树右子树前序遍历、中序遍历&#xff0c;后序遍历先根遍历、中根遍历左孩子右孩子题目…...

cocos creator 3.x版本如何添加打开游戏时首屏加载进度条

前言 项目有一个打开游戏时添加载入进度条的需求。这个功能2.X版本是自带的&#xff0c;不知为何在3.X版本中移除了。 实现 先说一下解决思路&#xff0c;就是在引擎源码加载场景的位置插入一个方法&#xff0c;然后在游戏入口HTML处监听即可。 1.找到对应源码脚本 在coco…...

Fama MacBeth两步法与多因子模型的回归检验

Fama MacBeth两步法与多因子模型的回归检验 – 潘登同学的因子投资笔记 本文观点来自最近学习的石川老师《因子投资&#xff1a;方法与实践》一书 文章目录 Fama MacBeth两步法与多因子模型的回归检验 -- 潘登同学的因子投资笔记 多因子回归检验时序回归检验截面回归检验Fama–…...

IDEA 搭建 SpringBoot 项目之配置 Maven

目录 1?配置 Maven 1.1?打开 settings.xml 文件1.2?配置本地仓库路径1.3?配置中央仓库路径1.4?配置 JDK 版本1.5?重新下载项目依赖 2?配置 idea 2.1?在启动页打开设置2.2?配置 Java Compiler2.3?配置 File Encodings2.4?配置 Maven2.5?配置 Auto Import2.6?配置 C…...

node.js之---事件循环机制

事件循环机制 Node.js 事件循环机制&#xff08;Event Loop&#xff09;是其核心特性之一&#xff0c;它使得 Node.js 能够高效地处理大量并发的 I/O 操作。Node.js 基于 非阻塞 I/O&#xff0c;使用事件驱动的模型来实现异步编程。事件循环是 Node.js 实现异步编程的基础&…...

Python OpenAI 库开发指南:从入门到实战精通

在人工智能&#xff08;AI&#xff09;领域&#xff0c;OpenAI无疑是全球最受瞩目的机构之一。它推出的GPT系列模型、DALLE等创新技术&#xff0c;正在深刻改变各行各业。作为Python开发者&#xff0c;我们该如何快速上手并高效利用OpenAI的API&#xff0c;成为了提升个人竞争力…...

flash-attention保姆级安装教程

FlashAttention安装教程 FlashAttention 是一种高效且内存优化的注意力机制实现&#xff0c;旨在提升大规模深度学习模型的训练和推理效率。 高效计算&#xff1a;通过优化 IO 操作&#xff0c;减少内存访问开销&#xff0c;提升计算效率。 内存优化&#xff1a;降低内存占用…...

送给一年编程道路的自己

回望过去一年在编程道路上的成长与收获&#xff0c;是一个很有意义的过程。总结自己这一年的编程经历&#xff0c;不仅可以帮助你更清晰地了解自己的进步和不足&#xff0c;还能为未来的发展指引方向。以下是一些可能的收获&#xff0c;供你参考&#xff1a; 1. 技能提升 语言…...

LeRobot(1)

Train python lerobot/scripts/train.py \ policyact \ envaloha \ env.taskAlohaInsertion-v0 \ dataset_repo_idlerobot/aloha_sim_insertion_human \ load_data一直报错&#xff0c;忘记截图了&#xff0c;反正是ssh报错&#xff0c;下不下来&#xff0c;网…...

C++ 设计模式:组合模式(Composite Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 迭代器模式 链接&#xff1a;C 设计模式 - 职责链模式 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式…...

OpenHarmony源码编译后烧录镜像教程,RK3566鸿蒙开发板演示

本文介绍瑞芯微主板/开发板编译OpenHarmony源码后烧录镜像的教程&#xff0c;触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器&#xff0c;树莓派卡片电脑设计&#xff0c;支持开源鸿蒙OpenHarmony3.2-5.0系统&#xff0c;适合鸿蒙开发入门学习。 编译源码…...

强化学习(1)

Reinforcement Learning Goal-directed learing from ineraction with the environment. 1. Basic Element 基本元素 1.1 Agent 玩家 1.2 Environment 1.3 Goal 2. Main Element 主要元素 2.1 State 2.2 Action 状态与行为往复 2.3 Reward 目标&#xff1a;最大化总…...

【漏洞复现】金和OA C6 FileDownLoad.aspx 任意文件读取漏洞复现

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…...

开源模型应用落地-qwen2-7b-instruct-LoRA微调-Axolotl-单机多卡-RTX 4090双卡(七)

一、前言 本篇文章将使用Axolotl去高效微调QWen2系列模型,通过阅读本文,您将能够更好地掌握这些关键技术,理解其中的关键技术要点,并应用于自己的项目中。 二、术语介绍 2.1. LoRA微调 LoRA (Low-Rank Adaptation) 用于微调大型语言模型 (LLM)。 是一种有效的自适应策略,…...

Dockerfile 构建继承父镜像的 ENTRYPOINT 和 CMD

在 Docker 中&#xff0c;Dockerfile 是否继承其父映像的 ENTRYPOINT 和 CMD&#xff0c;取决于 Dockerfile 的编写方式。以下是规则&#xff1a; 1. CMD 的继承 子镜像会继承父映像的 CMD&#xff0c;但如果在子镜像的 Dockerfile 中显式定义了新的 CMD&#xff0c;就会覆盖…...

46. Three.js案例-创建颜色不断变化的立方体模型

46. Three.js案例-创建颜色不断变化的立方体模型 实现效果 知识点 Three.js基础组件 WebGLRenderer THREE.WebGLRenderer是Three.js提供的用于渲染场景的WebGL渲染器。它支持抗锯齿处理&#xff0c;可以设置渲染器的大小和背景颜色。 构造器 antialias: 是否开启抗锯齿&am…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...