当前位置: 移动技术网 > IT编程>开发语言>JavaScript > vue+canvas实现移动端手写签名

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

2020年06月23日  | 移动技术网IT编程  | 我要评论

本文实例为大家分享了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排列在列表。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网