使用vue实现一个电子签名组件的示例代码


Posted in Javascript onJanuary 06, 2020

在生活中我们使用到电子签名最多的地方可能就是银行了,每次都会让你留下大名。今天我们就要用vue实现一个电子签名的面板

想要绘制图形,第一步想到的就是使用canvas标签,在之前的文章里我们使用canvas实现了一个前端生成图形验证码的组件,被吐槽不够安全,那么这个电子签名组件想必不会被吐槽了吧~

canvas

<canvas> 标签是 HTML 5 中的新标签。
<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。

canvas标签本身是没有绘图能力的,所有的绘制工作必须在 JavaScript 内部完成。

使用canvas绘图有几个必要的步骤:

  1. 获取canvas元素
  2. 通过canvas元素创建context对象
  3. 通过context对象来绘制图形

在当前电子签名需求中,由于签名其实是由一条条线组成的,因此我们会用到以下几个方法:

  1. beginPath() :开始一条路径或重置当前的路径
  2. moveTo():把路径移动到画布中的指定点,不创建线条
  3. lineTo():添加一个新点,然后在画布中创建从该点到最后指定点的线条
  4. stroke():绘制已定义的路径
  5. closePath():创建从当前点回到起始点的路径

事件

想要在canvas中绘图,还需要绑定几个特定的事件,而这些事件在pc端和手机端不尽相同

pc端事件

  • mousedown
  • mousemove
  • mouseup

手机端事件

  • touchstart
  • touchmove
  • touchend

核心代码

初始化canvas标签并绑定事件

<canvas
    @touchstart="touchStart"
    @touchmove="touchMove"
    @touchend="touchEnd"
    ref="canvasF"
    @mousedown="mouseDown"
    @mousemove="mouseMove"
    @mouseup="mouseUp"
   ></canvas>

获取画笔

在mounted生命周期初始化

mounted() {
  let canvas = this.$refs.canvasF;
  canvas.height = this.$refs.canvasHW.offsetHeight - 100;
  canvas.width = this.$refs.canvasHW.offsetWidth - 10;
  this.canvasTxt = canvas.getContext("2d");
  this.canvasTxt.strokeStyle = this.color;
  this.canvasTxt.lineWidth = this.linewidth;
 }

事件处理

mouseDown

//电脑设备事件
  mouseDown(ev) {
   ev = ev || event;
   ev.preventDefault();

   let obj = {
    x: ev.offsetX,
    y: ev.offsetY
   };
   this.startX = obj.x;
   this.startY = obj.y;
   this.canvasTxt.beginPath();//开始作画
   this.points.push(obj);//记录点
   this.isDown = true;
  },

touchStart

//移动设备事件
  touchStart(ev) {
   ev = ev || event;
   ev.preventDefault();
   if (ev.touches.length == 1) {
    this.isDraw = true; //签名标记
    let obj = {
     x: ev.targetTouches[0].clientX,
     y:
      ev.targetTouches[0].clientY -
      (document.body.offsetHeight * 0.5 +
       this.$refs.canvasHW.offsetHeight * 0.1)
    }; //y的计算值中:document.body.offsetHeight*0.5代表的是除了整个画板signatureBox剩余的高,this.$refs.canvasHW.offsetHeight*0.1是画板中标题的高
    this.startX = obj.x;
    this.startY = obj.y;
    this.canvasTxt.beginPath();//开始作画
    this.points.push(obj);//记录点
   }
  },

mouseMove

//电脑设备事件
  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.moveTo(this.startX, this.startY);//移动画笔
    this.canvasTxt.lineTo(obj.x, obj.y);//创建线条
    this.canvasTxt.stroke();//画线
    this.startY = obj.y;
    this.startX = obj.x;
    this.points.push(obj);//记录点
   }
  },

touchMove

//移动设备事件
  touchMove(ev) {
   ev = ev || event;
   ev.preventDefault();
   if (ev.touches.length == 1) {
    let obj = {
     x: ev.targetTouches[0].clientX,
     y:
      ev.targetTouches[0].clientY -
      (document.body.offsetHeight * 0.5 +
       this.$refs.canvasHW.offsetHeight * 0.1)
    };
    this.moveY = obj.y;
    this.moveX = obj.x;
    this.canvasTxt.moveTo(this.startX, this.startY);//移动画笔
    this.canvasTxt.lineTo(obj.x, obj.y);//创建线条
    this.canvasTxt.stroke();//画线
    this.startY = obj.y;
    this.startX = obj.x;
    this.points.push(obj);//记录点
   }
  },

mouseUp

//电脑设备事件
  mouseUp(ev) {
   ev = ev || event;
   ev.preventDefault();
   if (1) {
    let obj = {
     x: ev.offsetX,
     y: ev.offsetY
    };
    this.canvasTxt.closePath();//收笔
    this.points.push(obj);//记录点
    this.points.push({ x: -1, y: -1 });
    this.isDown = false;
   }
  },

touchEnd

//移动设备事件
  touchEnd(ev) {
   ev = ev || event;
   ev.preventDefault();
   if (ev.touches.length == 1) {
    let obj = {
     x: ev.targetTouches[0].clientX,
     y:
      ev.targetTouches[0].clientY -
      (document.body.offsetHeight * 0.5 +
       this.$refs.canvasHW.offsetHeight * 0.1)
    };
    this.canvasTxt.closePath();//收笔
    this.points.push(obj);//记录点
    this.points.push({ x: -1, y: -1 });//记录点
   }
  },

重写

发现自己写错字了,擦掉画板重新写过

//重写
  overwrite() {
   this.canvasTxt.clearRect(
    0,
    0,
    this.$refs.canvasF.width,
    this.$refs.canvasF.height
   );
   this.points = [];
   this.isDraw = false; //签名标记
  },

用到的data

data() {
  return {
   points: [],
   canvasTxt: null,
   startX: 0,
   startY: 0,
   moveY: 0,
   moveX: 0,
   endY: 0,
   endX: 0,
   w: null,
   h: null,
   isDown: false,
   color: "#000",
   linewidth: 3,
   isDraw: false //签名标记
  };
 },

使用vue实现一个电子签名组件的示例代码

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

Javascript 相关文章推荐
JavaScript 轻松搞定快捷留言功能 只需一行代码
Apr 01 Javascript
jQuery 源码分析笔记(7) Queue
Jun 19 Javascript
JS控件的生命周期介绍
Oct 22 Javascript
JS设置下拉列表框当前所选值的方法
Dec 22 Javascript
Jquery轮播效果实现过程解析
Mar 30 Javascript
jQuery实现div横向拖拽排序的简单实例
Jul 13 Javascript
浅谈JS运算符&amp;&amp;和|| 及其优先级
Aug 10 Javascript
轻松掌握JavaScript状态模式
Sep 07 Javascript
javascript淘宝主图放大镜功能
Oct 20 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
Jul 07 Javascript
vuejs中父子组件之间通信方法实例详解
Jan 17 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
Jul 21 Javascript
Vuejs中的watch实例详解(监听者)
Jan 05 #Javascript
Node中对非阻塞I/O、事件循环的知识点总结
Jan 05 #Javascript
原生js实现文件上传、下载、封装等实例方法
Jan 05 #Javascript
详解jQuery中的prop()使用方法
Jan 05 #jQuery
vue 对axios get pust put delete封装的实例代码
Jan 05 #Javascript
JavaScript修改注册表实例代码
Jan 05 #Javascript
详解JavaScript修改注册表的方法
Jan 05 #Javascript
You might like
用来给图片加水印的PHP类
2008/04/09 PHP
php报表之jpgraph柱状图实例代码
2011/08/22 PHP
php explode函数实例代码
2012/02/27 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
js实现简单模态窗口,背景灰显
2008/11/14 Javascript
jQuery textarea的长度进行验证
2009/05/06 Javascript
JavaScript Event学习第二章 Event浏览器兼容性
2010/02/07 Javascript
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
2010/11/28 Javascript
JavaScript XML和string相互转化实现代码
2011/07/04 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
JavaScript的jQuery库中ready方法的学习教程
2015/08/14 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
Nodejs基于LRU算法实现的缓存处理操作示例
2017/03/17 NodeJs
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
js中innerText/textContent和innerHTML与target和currentTarget的区别
2019/01/21 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
js获取form表单中name属性的值
2019/02/27 Javascript
vue2.0自定义指令示例代码详解
2019/04/25 Javascript
在vue中封装的弹窗组件使用队列模式实现方法
2020/07/23 Javascript
Python中random模块用法实例分析
2015/05/19 Python
Python 3中的yield from语法详解
2017/01/18 Python
利用Python将时间或时间间隔转为ISO 8601格式方法示例
2017/09/05 Python
Python实现重建二叉树的三种方法详解
2018/06/23 Python
python 实现数字字符串左侧补零的方法
2018/12/04 Python
在OpenCV里使用Camshift算法的实现
2019/11/22 Python
Python表达式的优先级详解
2020/02/18 Python
英国领先的酒杯和水晶玻璃器皿制造商:Dartington Crystal
2019/06/23 全球购物
逻辑链路控制协议
2016/10/01 面试题
美德好少年主要事迹
2014/01/29 职场文书
庆祝教师节演讲稿
2014/09/03 职场文书
2015年污水处理厂工作总结
2015/05/26 职场文书
伊索寓言读书笔记
2015/06/30 职场文书
宣传部部长竞选稿
2015/11/21 职场文书
详解redis分布式锁的这些坑
2021/05/19 Redis
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL