vue+canvas實現移動端手寫簽名
阿新 • • 發佈:2020-05-23
本文例項為大家分享了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,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,//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,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,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,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,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,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,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,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排列在列表。
重籤就是刪除列表所有圖片,提交就是將多張圖合併為一張且傳給前一頁顯示。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。