Vue Canvas实现电子签名
更新时间:2022年07月21日 10:15:01 作者:岁末Zzz
这篇文章主要为大家详细介绍了Vue Canvas实现电子签名,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
最近再做移动端电子签名,Vue+Canvas实现,移动端、PC端均可,也可以从github下载 。
我在做这个功能的时候参考了 这个代码,但是在移动端光标与实际划线有偏移,我在我的代码中修正了这个问题。
代码
<template> <section class="signature"> <div class="signatureBox"> <div class="canvasBox" ref="canvasHW"> <canvas ref="canvasF" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd' @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"></canvas> <div class="btnBox"> <div @click="overwrite">重写</div> <div @click="commit">提交签名</div> </div> </div> </div> <img class="imgCanvas" :src="imgUrl"> </section> </template>
JS
<script> export default { data() { return { stageInfo:'', imgUrl:'', client: {}, points: [], canvasTxt: null, startX: 0, startY: 0, moveY: 0, moveX: 0, endY: 0, endX: 0, w: null, h: null, isDown: false, isViewAutograph: this.$route.query.isViews > 0, contractSuccess: this.$route.query.contractSuccess } }, mounted() { let canvas = this.$refs.canvasF canvas.height = this.$refs.canvasHW.offsetHeight - 500 canvas.width = this.$refs.canvasHW.offsetWidth - 50 this.canvasTxt = canvas.getContext('2d') this.stageInfo = canvas.getBoundingClientRect() }, methods: { //mobile touchStart(ev) { ev = ev || event ev.preventDefault() if (ev.touches.length == 1) { let obj = { x: ev.targetTouches[0].clienX, y: ev.targetTouches[0].clientY, } this.startX = obj.x this.startY = obj.y this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.points.push(obj) } }, touchMove(ev) { ev = ev || event ev.preventDefault() if (ev.touches.length == 1) { let obj = { x: ev.targetTouches[0].clientX - this.stageInfo.left, y: ev.targetTouches[0].clientY - this.stageInfo.top } this.moveY = obj.y this.moveX = obj.x this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.startY = obj.y this.startX = obj.x this.points.push(obj) } }, touchEnd(ev) { ev = ev || event ev.preventDefault() if (ev.touches.length == 1) { let obj = { x: ev.targetTouches[0].clientX - this.stageInfo.left, y: ev.targetTouches[0].clientY - this.stageInfo.top } this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.points.push(obj) } }, //pc mouseDown(ev) { ev = ev || event ev.preventDefault() if (1) { let obj = { x: ev.offsetX, y: ev.offsetY } this.startX = obj.x this.startY = obj.y this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.points.push(obj) this.isDown = true } }, mouseMove(ev) { ev = ev || event ev.preventDefault() if (this.isDown) { let obj = { x: ev.offsetX, y: ev.offsetY } this.moveY = obj.y this.moveX = obj.x this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.startY = obj.y this.startX = obj.x this.points.push(obj) } }, mouseUp(ev) { ev = ev || event ev.preventDefault() if (1) { let obj = { x: ev.offsetX, y: ev.offsetY } this.canvasTxt.beginPath() this.canvasTxt.moveTo(this.startX, this.startY) this.canvasTxt.lineTo(obj.x, obj.y) this.canvasTxt.stroke() this.canvasTxt.closePath() this.points.push(obj) this.points.push({x: -1, y: -1}) this.isDown = false } }, //重写 overwrite() { this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height) this.points = [] }, //提交签名 commit() { this.imgUrl=this.$refs.canvasF.toDataURL(); console.log(this.$refs.canvasF.toDataURL()) //签名img回传后台 } } } </script>
CSS
<style scoped> .signatureBox { width: 100%; height: calc(100% - 50px); box-sizing: border-box; overflow: hidden; background: #fff; z-index: 100; display: flex; flex-direction: column; } .canvasBox { box-sizing: border-box; flex: 1; } canvas { border: 1px solid #7d7d7d; } .btnBox { padding: 10px; text-align: center; } .btnBox button:first-of-type { background: transparent; border-radius: 4px; height: 40px; width: 80px; font-size: 14px; } .btnBox button:last-of-type { background: #71b900; color: #fff; border-radius: 4px; height: 40px; width: 80px; font-size: 14px; } </style>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
vue el-form一行里面放置多个el-form-item的实现
本文主要介绍了vue el-form一行里面放置多个el-form-item的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-08-08Vue 路由间跳转和新开窗口的方式(query、params)
这篇文章主要介绍了Vue 路由间跳转和新开窗口的方式,本文主要通过query方式和params方式介绍,需要的朋友可以参考下2019-12-12vue中@click和@click.native.prevent的区别
这篇文章主要介绍了vue中@click和@click.native.prevent的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-04-04vueJs函数readonly与shallowReadonly使用对比详解
这篇文章主要为大家介绍了vueJs函数readonly与shallowReadonly使用对比详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-03-03vue 2 实现自定义组件一到多个v-model双向数据绑定的方法(最新推荐)
有时候我们需要对一个组件绑定自定义 v-model,以更方便地实现双向数据,例如自定义表单输入控件,这篇文章主要介绍了vue 2 实现自定义组件一到多个v-model双向数据绑定的方法,需要的朋友可以参考下2024-07-07Element ui table表格内容超出隐藏显示省略号问题
这篇文章主要介绍了Element ui table表格内容超出隐藏显示省略号问题,具有很好的参考价值,希望对大家有所帮助,2023-11-11
最新评论