vue+canvas实现移动端手写签名
程序员文章站
2022-06-25 12:58:22
本文实例为大家分享了vue+canvas实现移动端手写签名的具体代码,供大家参考,具体内容如下
本文实例为大家分享了vue+canvas实现移动端手写签名的具体代码,供大家参考,具体内容如下
<template> <div class="sign"> <div class="header"> <i class="el-icon-arrow-left backimg" @click="goback"></i> <span class="title">个人签名</span> </div> <section class="signature"> <div class="signaturebox"> <div class="canvasbox" ref="canvashw"> <canvas ref="canvasf" class="canvasstyle" @touchstart='touchstart' @touchmove='touchmove' @touchend='touchend' @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup"></canvas> </div> </div> </section> <div class="btnbox"> <div @click="overwrite" class="btn1">重置</div> <div @click="commit" class="btn1">确定</div> </div> <div class="imglist-box" :style="imgurllist.length>0 ? 'border: 1px solid #d9d9d9;' : ''"> <img v-for="i in imgurllist" class="imgcanvas" :src="i"> <img v-show="imgurllist.length>0" src="../../assets/img/signdelete.png" class="resign" @click="deleteall"> </div> <div class="tijiao-box"> <button @click="commitall" class="tijiao">提 交</button> </div> </div> </template> <script> import { bus } from '@/utils' export default { name:'personsign', data() { return { stageinfo:'', imgurl:'', imgurllist:[], 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 -0 canvas.width = this.$refs.canvashw.offsetwidth - 0 this.canvastxt = canvas.getcontext('2d') this.canvastxt.linewidth = 4 this.stageinfo = canvas.getboundingclientrect() }, methods: { goback(){ this.$router.go(-1) // session.clear() }, //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.strokerect(20,20,80,100); 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(); this.imgurllist.push(this.imgurl) if(this.imgurllist.length>0){ this.canvastxt.clearrect(0, 0, this.$refs.canvasf.width, this.$refs.canvasf.height) this.points = [] } }, deleteall(){ this.imgurllist = [] }, // 提交签名给前一页 commitall(){ // 用canvas合并多张图片的base64为一张图的base64 var canvas = document.createelement("canvas"); canvas.width = 75*this.imgurllist.length; canvas.height = 100; var context = canvas.getcontext("2d"); context.rect(0 , 0 , canvas.width , canvas.height); context.fillstyle = "#fff"; context.fill(); var myimage = new image(); myimage.crossorigin = 'anonymous'; // 当签名列表有值时 if(this.imgurllist.length>0){ for(let i = 0;i<this.imgurllist.length;i++){ myimage.src = this.imgurllist[i] // 多张图片绘制成一张图片 context.drawimage(myimage , 50*i , 0 , 75 , 75); //context.drawimage(img,x,y,width,height); // context.font = "60px courier new"; // context.filltext("我是文字",350,450); } var base64 = canvas.todataurl("image/jpg"); //"image/jpg" 这里注意一下 this.$router.go(-1) //要在bus之前写不然值传不回去 settimeout(() => { bus.$emit('signimage',base64) //签名base64传给前一页 }, 300) } } }, beforedestroy(){ // 销毁bus bus.$off() } } </script> <style scoped lang="scss"> // 签名样式很重要,会影响触点位置 .sign{ width: 100%; min-height: 100vh; position: relative; .header{ margin-bottom: 20px; } .tijiao-box{ width: 100%; text-align: center; } .tijiao{ width: 90%; height: 84px; color: #fff; border-radius: 2px; background: #fa4b31; box-shadow: 0 0 0px 1px #fa4b31; font-size: 30px; } } .signature{ width: 100%; height: 50vh; } .imglist-box{ width: 90%; margin: 0 auto; margin-bottom: 20px; position: relative; } .imgcanvas{ width: 150px; height: 150px; } .resign{ width: 14%; position: absolute; top: 0; right: 0; } .signaturebox { width: 90%; margin: 0 auto; height: calc(100% - 50px); box-sizing: border-box; overflow: hidden; background: #fff; z-index: 100; display: flex; flex-direction: column; align-items: center; } .canvasbox { width: 100%; align-items: center; box-sizing: border-box; flex: 1; } canvas { background-image: url('../../assets/img/signbg.png'); background-position: center center; background-repeat: no-repeat; background-origin: border-box; background-size: 100% 100%; } .btnbox{ width: 90%; margin: 0 auto; display: flex; justify-content: space-between; margin-bottom: 20px; .btn1{ width: 46%; height: 84px; line-height: 84px; color: #fa4b31; border-radius: 2px; background: #fff; border: 1px solid #fa4b31; box-shadow: 0 0 0px 1px #fa4b31; font-size: 30px; 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>
重置就是清除田字格当前字,确定就将字保存为一张图片base64排列在列表。
重签就是删除列表所有图片,提交就是将多张图合并为一张且传给前一页显示。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 只要你不表白
下一篇: Vue如何获取数据列表展示