网络编程
位置:首页>> 网络编程>> JavaScript>> vue+canvas实现移动端手写签名

vue+canvas实现移动端手写签名

作者:XingFang666  发布时间:2024-07-12 04:11:59 

标签: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>

vue+canvas实现移动端手写签名

vue+canvas实现移动端手写签名

vue+canvas实现移动端手写签名

重置就是清除田字格当前字,确定就将字保存为一张图片base64排列在列表。

重签就是删除列表所有图片,提交就是将多张图合并为一张且传给前一页显示。

来源:https://blog.csdn.net/xfmuchengxue/article/details/95175455

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com