使用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 css float属性的特殊写法
Nov 13 Javascript
javascript 折半查找字符在数组中的位置(有序列表)
Dec 09 Javascript
jquery移动listbox的值原理及代码
May 03 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
Oct 10 Javascript
整理Javascript事件响应学习笔记
Dec 02 Javascript
简述jQuery ajax的执行顺序
Jan 05 Javascript
Node.js中用D3.js的方法示例
Jan 16 Javascript
webpack external模块的具体使用
Mar 10 Javascript
JS实现将链接生成二维码并转为图片的方法
Mar 17 Javascript
解析Json字符串的三种方法日常常用
May 02 Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 Javascript
Vue + ts实现轮播插件的示例
Nov 10 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实现根据url自动生成缩略图的方法
2014/09/23 PHP
PHP简单留言本功能实现代码
2017/06/09 PHP
PHP封装的PDO数据库操作类实例
2017/06/21 PHP
什么是PHP文件?如何打开PHP文件?
2017/06/27 PHP
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
jquery ui dialog实现弹窗特效的思路及代码
2013/08/03 Javascript
js实现带圆角的多级下拉菜单效果
2015/08/28 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
JS插件plupload.js实现多图上传并显示进度条
2016/11/29 Javascript
Vue 实用分页paging实例代码
2017/04/12 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
微信小程序解析富文本过程详解
2019/07/13 Javascript
[01:15:18]2014 DOTA2国际邀请赛中国区预选赛 LGD VS Speed Gaming.cn
2014/05/22 DOTA
[18:16]sakonoko 2017年卡尔集锦
2018/02/06 DOTA
Python函数式编程指南(一):函数式编程概述
2015/06/24 Python
python嵌套字典比较值与取值的实现示例
2017/11/03 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
对Python定时任务的启动和停止方法详解
2019/02/19 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
python检测服务器端口代码实例
2019/08/31 Python
python实现的分层随机抽样案例
2020/02/25 Python
Python+OpenCV图像处理—— 色彩空间转换
2020/10/22 Python
HTML5超文本标记语言的实现方法
2020/09/24 HTML / CSS
Blue Nile中国官网:全球知名的钻石和珠宝网络零售商
2020/03/22 全球购物
事假请假条范文
2014/04/11 职场文书
亲子活动总结
2014/04/26 职场文书
不错的求职信范文
2014/07/20 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
2014年公路养护工作总结
2014/12/04 职场文书
庆祝教师节活动总结
2015/03/23 职场文书
失恋33天观后感
2015/06/11 职场文书
导游词之南昌滕王阁
2019/11/29 职场文书
Golang中interface{}转为数组的操作
2021/04/30 Golang
JS + HTML 罗盘式时钟的实现
2021/05/21 Javascript
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android