vue需求:实现签章/签字在页面上自由定位的功能(本质:元素在页面上的拖拽)

本文主要是介绍vue需求:实现签章/签字在页面上自由定位的功能(本质:元素在页面上的拖拽),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

第一章  效果展示

第二章  了解工具

2.1 draggable

2.1.1 了解draggable

2.1.2 draggable方法

2.1.3 利用例子理解方法

第三章 效果实现

3.1 实现思路

3.2 代码实现

3.2.1 涉及到的点

3.2.2 源代

第一章  效果展示

  • 效果描述:通过点击左边栏的签名和签章,使其在右边初步展示,然后再拖动确定他们的位置

第二章  了解工具

2.1 draggable

2.1.1 了解draggable

  • draggable 属性是 HTML5 新增的。
  • Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 浏览器支持 draggable 属性,IE8以下不支持
  • draggable 属性规定元素是否可拖动
  • 用法:
<element draggable="true|false|auto">
  • 注意: 图片(<img>)和链接(<a>)不加这个属性,就可以拖拉,对于它们,为了防止拖拽,用到这个属性的时候,往往是将其设为false
  • 说明:
true规定元素是可拖动的。
false规定元素是不可拖动的。
auto使用浏览器的默认特性。

2.1.2 draggable方法

  • drag拖拽过程中,在被拖拽的节点上持续触发(相隔几百毫秒)。
  • dragstart用户拖拽开始时,在被拖拽的节点上触发,该事件的target属性是被拖拉的节点。通常在这个事件的监听函数中,指定拖拽的数据。(常用)
  • dragend拖拽结束时(释放鼠标键或按下 ESC 键)在被拖拽的节点上触发,该事件的target属性是被拖拉的节点。它与dragstart事件,在同一个节点上触发。不管拖拉是否跨窗口,或者中途被取消,dragend事件总是会触发的。(常用)
  • dragenter拖拽进入当前节点时,在当前节点上触发一次,该事件的target属性是当前节点。通常应该在这个事件的监听函数中,指定是否允许在当前节点放下(drop)拖拉的数据。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据。在视觉上显示拖拉进入当前节点,也是在这个事件的监听函数中设置。
  • dragover拖拉到当前节点上方时,在当前节点上持续触发(相隔几百毫秒),该事件的target属性是当前节点。该事件与dragenter事件的区别是,dragenter事件在进入该节点时触发,然后只要没有离开这个节点,dragover事件会持续触发
  • dragleave拖拉操作离开当前节点范围时,在当前节点上触发,该事件的target属性是当前节点。如果要在视觉上显示拖拉离开操作当前节点,就在这个事件的监听函数中设置。
  • drop被拖拉的节点或选中的文本,释放到目标节点时,在目标节点上触发。注意,如果当前节点不允许drop,即使在该节点上方松开鼠标键,也不会触发该事件。如果用户按下 ESC 键,取消这个操作,也不会触发该事件。该事件的监听函数负责取出拖拉数据,并进行相关处理。

2.1.3 利用例子理解方法

<div class="back_box" ref="back_box"><divv-if="signShow"class="drag_box"draggable="true"@drag="drag($event)"@dragstart="dragstart($event)"@dragend="dragend($event)"@dragenter="dragenter($event)"@dragover="dragover($event)"@dragleave="dragleave($event)"@drop="drop($event)":style="`left:${elLeft}px;top:${elTop}px`">
</div>drag(e){console.log('drag', e)
},
// 拖拽开始事件
dragstart (e) {console.log('dragstart', e)
},
// 拖拽完成事件
dragend (e) {console.log('dragend', e)
},
dragenter (e) {console.log('dragenter', e)
},
dragover (e) {console.log('dragover', e)
},
dragleave (e) {console.log('dragleave', e)
},
  • 看效果

  • 看右边输出,很明显,小编开始拖拽时,dragstart函数调用,然后drag-> dragenter->dragover调用,这一过程是表示拖拽过程中进入了节点同时还在该节点上方的范围内,后面输出从drag->dragoverdrag->drag…的原因也是在拖拽的过程中,节点由原来的节点上方范围内到范围外之后只有drag触发,dragover不触发,最后松开鼠标,拖拽结束了,触发dragend
  •  至于为什么drop没有触发,这里请看文档的实例,如下。(小编理解是,该事件应该在存放的目标模板中使用,而不是自身)

HTML draggable 属性 | 菜鸟教程

  • event的参数(小编就不一一说明了,这里用到clientX和clientY计算偏移量的)

 

第三章 效果实现

3.1 实现思路

  • 三个元素:签名、签章已经模板
  • 页面布局,初步样式控制,小编的样式:(为了方便,小编模板用的图片-->大家用源代码时记得替换)

  •  点击左边的签名,右边模板出现对应的签名,签章同理,利用定位让签章与签名都在模板的左上角
  • 拖拽开始时记录一次最开始的位置
  • 拖拽结束鼠标松开时再记录一次位置
  • 利用两个位置的差计算偏移量
  • 最后再次利用定位top和left将签名和签章固定到模板上

3.2 代码实现

3.2.1 涉及到的点

  • 使用dragstart和dragend记录拖拽元素初始位置和结束位置
  • 利用宽高比例进行页面初始化(正常屏幕宽高1920*1080,根据需求初始化)
  • 了解一下
  1. clientX:当鼠标事件发生时(不管是onclick,还是omousemovenmouseover等),鼠标对于浏览器(这里说的是浏览器的有效区域)x抽的置
  2. clientY:当鼠标事件发生时,鼠标相对于浏览器(这里说的是浏览器的有效区域)y轴的位置;
  3. screenX:当鼠标事件发生时,鼠标相对于显示器屏幕x轴的位置;
  4. screenY:当鼠标事件发生时,鼠标相对于显示器屏幕y轴的位置;
  5. offsetX:当鼠标事件发生时,鼠标相对于事件源x轴的位置(这里的事件源是上一个有定位的父级标签)
  6. offsetY:当鼠标事件发生时,鼠标相对于事件源y轴的位置(这里的事件源是上一个有定位的父级标签)

3.2.2 源代码

<template><div class="page"><div class="left"><div class="title">签名</div><div class="img" @click="signShow = true"><img src="./img/sign.png" alt="" style="height: 50px; border: 1px solid #eee;"></div><div class="title">签章</div><div class="img" @click="sign2Show = true"><img src="./img/sign3.png" alt=""></div></div><div class="right"><div class="drag"><div class="back_box" ref="back_box"><divv-if="signShow"class="drag_box"draggable="true"@dragstart="dragstart($event)"@dragend="dragend($event)":style="`left:${elLeft}px;top:${elTop}px`"></div><divv-if="sign2Show"class="drag_box2"draggable="true"@dragstart="sign2dragstart($event)"@dragend="sign2dragend($event)":style="`left:${elLeft2}px;top:${elTop2}px`"></div></div></div></div></div>
</template><script>
export default {name: 'HelloWorld',data () {return {initWidth: 0, // 父元素的宽-自适应值initHeight: 0, // 父元素的高-自适应值startclientX: 0, // 元素拖拽前距离浏览器的X轴位置startclientY: 0, // 元素拖拽前距离浏览器的Y轴位置elLeft: 0, // 元素的左偏移量elTop: 0, // 元素的右偏移量,startclientX2: 0, // 元素拖拽前距离浏览器的X轴位置startclientY2: 0, // 元素拖拽前距离浏览器的Y轴位置elLeft2: 0, // 元素的左偏移量elTop2: 0, // 元素的右偏移量,signShow: false,sign2Show: false,}},components: {},methods: {// 页面初始化initBodySize () {this.initWidth = this.$refs.back_box.clientWidth // 拿到父元素宽this.initHeight = this.initWidth * (1080 / 1920) // 根据宽计算高实现自适应},// 拖拽开始事件dragstart (e) {this.startclientX = e.clientX // 记录拖拽元素初始位置this.startclientY = e.clientY},// 拖拽完成事件dragend (e) {let x = e.clientX - this.startclientX // 计算偏移量let y = e.clientY - this.startclientYthis.elLeft += x // 实现拖拽元素随偏移量移动this.elTop += y},// 拖拽开始事件sign2dragstart (e) {this.startclientX2 = e.clientX // 记录拖拽元素初始位置this.startclientY2 = e.clientY},// 拖拽完成事件sign2dragend (e) {let x = e.clientX - this.startclientX2 // 计算偏移量let y = e.clientY - this.startclientY2this.elLeft2 += x // 实现拖拽元素随偏移量移动this.elTop2 += y}},mounted () {this.initBodySize()}
}
</script><style lang="less" scoped>
.page{width: 100vw;height: 100vh;background-color: #fff;display: flex;justify-content: flex-start;.left{width: 20%;height: 100%;cursor: pointer;border-right: 1px solid #eee;.title{font-size: 14px;margin: 16px;}.img{margin: 16px 50px 16px 16px;img{height: 100px;}}}.right{width: 80%;position: relative;height: 100%;.back_box {background-image: url('./img/bg.png');background-size: 100% 100%;background-repeat: no-repeat;width: 70%;height: 60%;position: absolute;top: 0;right: 0;bottom: 0;left: 0;margin: auto;}.drag_box {width: 150px;height: 50px;background-image: url('./img/sign.png');background-size: 100% 100%;background-repeat: no-repeat;position: absolute;z-index: 10;}.drag_box2 {width: 150px;height: 150px;background-image: url('./img/sign2.png');background-size: 100% 100%;background-repeat: no-repeat;position: absolute;z-index: 10;}}
}
</style>

第四章 扩展 

  • 如果该需求大家也需要应用时,如果后端做pdf,前后端首先确定一致的模板
  • 前端需要做的是将签名、签章的位置向后端提供(注意前端传的位置必须的等比例的,如果前端模板被用户缩小窗口使用的,提供的位置就不准确了),需要将签名签章的拥有者向后端提供
  • 如果后端不自己拿签名签章的图片,还需要将其路径向后端提供如果图片的宽高用户可以手动控制,前端还需要对对图片的宽高进行处理,获取到宽高然后向后端提供——这里小编有两个方法:一个是通过鼠标滚轮对图片缩放从而控制图片大小(onwheel);另个一个是输入控制,小编后续的文章会谈到
  • 如果直接让前端生成pdf,看该文章或许会有帮助:

需求:前端生成一个模板并盖章的pdf文件(单个文件自动下载+多文件生成压缩包下载以及window.print()),一个pdf多个分页进行处理(保证图片、表、文字能完整展示,截断问题解决)_❆VE❆的博客-CSDN博客

这篇关于vue需求:实现签章/签字在页面上自由定位的功能(本质:元素在页面上的拖拽)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345139

相关文章

Python中edge-tts实现便捷语音合成

《Python中edge-tts实现便捷语音合成》edge-tts是一个功能强大的Python库,支持多种语言和声音选项,本文主要介绍了Python中edge-tts实现便捷语音合成,具有一定的参考价... 目录安装与环境设置文本转语音查找音色更改语音参数生成音频与字幕总结edge-tts 是一个功能强大的

Java实现按字节长度截取字符串

《Java实现按字节长度截取字符串》在Java中,由于字符串可能包含多字节字符,直接按字节长度截取可能会导致乱码或截取不准确的问题,下面我们就来看看几种按字节长度截取字符串的方法吧... 目录方法一:使用String的getBytes方法方法二:指定字符编码处理方法三:更精确的字符编码处理使用示例注意事项方

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

PyQt5+Python-docx实现一键生成测试报告

《PyQt5+Python-docx实现一键生成测试报告》作为一名测试工程师,你是否经历过手动填写测试报告的痛苦,本文将用Python的PyQt5和python-docx库,打造一款测试报告一键生成工... 目录引言工具功能亮点工具设计思路1. 界面设计:PyQt5实现数据输入2. 文档生成:python-

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整