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


Posted in Javascript onMay 21, 2020

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 学习之一 对象访问
Nov 23 Javascript
jQuery中常用的遍历函数用法实例总结
Sep 01 Javascript
jquery.form.js框架实现文件上传功能案例解析(springmvc)
May 26 Javascript
jQuery实现可拖拽的许愿墙效果【附demo源码下载】
Sep 14 Javascript
jquery遍历标签中自定义的属性方法
Sep 17 Javascript
微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法示例
Oct 13 Javascript
jQuery实现立体式数字滚动条增加效果
Dec 21 Javascript
vue实现页面加载动画效果
Sep 19 Javascript
JS设计模式之命令模式概念与用法分析
Feb 06 Javascript
vue-cli下的vuex的简单Demo图解(实现加1减1操作)
Feb 26 Javascript
webpack 静态资源集中输出的方法示例
Nov 09 Javascript
基于ant design日期控件使用_仅月份的操作
Oct 27 Javascript
基于canvas实现手写签名(vue)
May 21 #Javascript
jQuery实现移动端笔触canvas电子签名
May 21 #jQuery
js cavans实现静态滚动弹幕
May 21 #Javascript
Object.keys() 和 Object.getOwnPropertyNames() 的区别详解
May 21 #Javascript
JavaScript实现HSL拾色器
May 21 #Javascript
js实现拾色器插件(ColorPicker)
May 21 #Javascript
原生js实现日期选择插件
May 21 #Javascript
You might like
解析php mysql 事务处理回滚操作(附实例)
2013/08/05 PHP
PHP之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
jQuery+php简单实现全选删除的方法
2016/11/28 PHP
PHP获取指定日期是星期几的实现方法
2016/11/30 PHP
老生常谈PHP面向对象之解释器模式
2017/05/17 PHP
网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
2018/10/23 PHP
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
2006/12/27 Javascript
Javascript 读书笔记索引贴
2010/01/11 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
Js 回车换行处理的办法及replace方法应用
2013/01/24 Javascript
js实现的折叠导航示例
2013/11/29 Javascript
深入理解JavaScript中的传值与传引用
2013/12/09 Javascript
JQuery实现防止退格键返回的方法
2015/02/12 Javascript
Sublime Text 3常用插件及安装方法
2015/12/16 Javascript
使用Node.js处理前端代码文件的编码问题
2016/02/16 Javascript
javascript中this指向详解
2016/04/23 Javascript
详解微信小程序开发之城市选择器 城市切换
2017/01/17 Javascript
详解angular2实现ng2-router 路由和嵌套路由
2017/03/24 Javascript
JavaScript实现淘宝京东6位数字支付密码效果
2018/08/18 Javascript
layui实现三级联动效果
2019/07/26 Javascript
利用JS代码自动删除稿件的普通弹幕功能
2019/09/20 Javascript
如何区分vue中的v-show 与 v-if
2020/09/08 Javascript
Chrome插件开发系列一:弹窗终结者开发实战
2020/10/02 Javascript
[48:54]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第二场 6.3
2018/06/04 DOTA
Python3 Tensorlfow:增加或者减小矩阵维度的实现
2020/05/22 Python
pycharm导入源码的具体步骤
2020/08/04 Python
Python类的继承super相关原理解析
2020/10/22 Python
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的
2015/07/23 面试题
经理职责范文
2013/11/08 职场文书
篮球比赛拉拉队口号
2014/06/10 职场文书
2015年南京大屠杀纪念日活动总结
2015/03/24 职场文书
大学生求职自荐信
2015/03/24 职场文书
2015年纪检监察工作总结
2015/04/08 职场文书
离婚案件答辩状
2015/05/22 职场文书
2016大学生暑期社会实践心得体会
2016/01/14 职场文书