使用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各种复制代码收集
Sep 20 Javascript
javascript options属性集合操作代码
Dec 28 Javascript
JavaScript Event学习第四章 传统的事件注册模型
Feb 07 Javascript
使用jQuery轻松实现Ajax的实例代码
Aug 16 Javascript
jquery中 $.expr使用实例介绍
Jun 09 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
Nov 07 Javascript
jquery自定义插件开发之window的实现过程
May 06 Javascript
JavaScript操作 url 中 search 部分方法函数
Jun 15 Javascript
jQuery基于ID调用指定iframe页面内的方法
Jul 06 Javascript
Angular2学习教程之TemplateRef和ViewContainerRef详解
May 25 Javascript
vue用Object.defineProperty手写一个简单的双向绑定的示例
Jul 09 Javascript
详解JavaScript中的Object.is()与&quot;===&quot;运算符总结
Jun 17 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变量可用字符
2014/05/28 PHP
PHP制作百度词典查词采集器
2015/01/29 PHP
php7函数,声明,返回值等新特性介绍
2018/05/25 PHP
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
javascript中的遍历for in 以及with的用法
2014/12/22 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
2015/03/23 Javascript
简单实现js间歇或无缝滚动效果
2016/06/29 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
2019/04/19 Javascript
javascript实现点亮灯泡特效示例
2019/10/15 Javascript
Python 命令行非阻塞输入的小例子
2013/09/27 Python
python实现绘制树枝简单示例
2014/07/24 Python
python人人网登录应用实例
2014/09/26 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
使用Python和xlwt向Excel文件中写入中文的实例
2018/04/21 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
python 信息同时输出到控制台与文件的实例讲解
2018/05/11 Python
用Python PIL实现几个简单的图片特效
2019/01/18 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
Python调用C语言的实现
2019/07/26 Python
Python pandas库中的isnull()详解
2019/12/26 Python
利用Python实现学生信息管理系统的完整实例
2020/12/30 Python
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
中国包裹转运寄送国际服务:Famiboat
2019/07/24 全球购物
耐克波兰官方网站:Nike波兰
2019/09/03 全球购物
逻辑链路控制协议
2016/10/01 面试题
大学本科毕业生求职简历的自我评价
2013/10/09 职场文书
小学生演讲稿
2014/01/12 职场文书
大学军训感言300字
2014/03/09 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书
Redis数据结构之链表与字典的使用
2021/05/11 Redis
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python
MySQL中EXPLAIN语句及用法
2022/05/20 MySQL