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 14 Javascript
JavaScript实现的一个日期格式化函数分享
Dec 06 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
Jun 06 Javascript
javascript将中国数字格式转换成欧式数字格式的简单实例
Aug 02 Javascript
BootStrap modal模态弹窗使用小结
Oct 26 Javascript
移动端日期插件Mobiscroll.js使用详解
Dec 19 Javascript
Javascript基础回顾之(三) js面向对象
Jan 31 Javascript
vuejs使用FormData实现ajax上传图片文件
Aug 08 Javascript
js防刷新的倒计时代码 js倒计时代码
Sep 06 Javascript
详解Vue如何支持JSX语法
Nov 10 Javascript
dts文件中删除一个node或属性的操作方法
Aug 05 Javascript
layui实现显示数据表格、搜索和修改功能示例
Jun 03 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
计数器详细设计
2006/10/09 PHP
PHP函数addslashes和mysql_real_escape_string的区别
2014/04/22 PHP
weiphp微信公众平台授权设置
2016/01/04 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
javascript的数据类型、字面量、变量介绍
2012/05/23 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
javascript制作坦克大战全纪录(2)
2014/11/27 Javascript
javascript跨域原因以及解决方案分享
2015/04/08 Javascript
JavaScript阻止回车提交表单的方法
2015/12/30 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
2016/01/22 Javascript
jQuery实现点击水纹波动动画
2016/04/10 Javascript
使用vue.js开发时一些注意事项
2016/04/27 Javascript
jQuery判断checkbox选中状态
2016/05/12 Javascript
jQuery Ztree行政地区树状展示(点击加载)
2016/11/09 Javascript
json数据处理及数据绑定
2017/01/25 Javascript
详解Node.js中exports和module.exports的区别
2017/04/19 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
vue发送ajax请求详解
2018/10/09 Javascript
基于javascript实现贪吃蛇小游戏
2019/11/25 Javascript
Nodejs实现WebSocket代码实例
2020/05/19 NodeJs
Python开发WebService系列教程之REST,web.py,eurasia,Django
2014/06/30 Python
python实现对excel进行数据剔除操作实例
2017/12/07 Python
Django框架HttpResponse对象用法实例分析
2019/11/01 Python
Python使用进程Process模块管理资源
2020/03/05 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
2020/08/22 Python
澳大利亚礼品卡商店:Gift Card Store
2019/06/24 全球购物
美国围栏公司:Walpole Outdoors
2019/11/19 全球购物
《石榴》教学反思
2014/03/02 职场文书
体育活动总结范文
2014/05/04 职场文书
幼师求职信
2014/06/23 职场文书
硕士论文致谢范文
2015/05/14 职场文书
干部外出学习心得体会
2016/01/18 职场文书
利用python Pandas实现批量拆分Excel与合并Excel
2021/05/23 Python
python for循环赋值问题
2021/06/03 Python