使用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 相关文章推荐
Jquery知识点二 jquery下对数组的操作
Jan 15 Javascript
最新28个很棒的jQuery 教程
May 28 Javascript
JavaScript高级程序设计(第3版)学习笔记13 ECMAScript5新特性
Oct 11 Javascript
javascript中的startWith和endWith的几种实现方法
May 07 Javascript
Javascript/Jquery——简单定时器的多种实现方法
Jul 03 Javascript
JS实现的生成随机数的4个函数分享
Feb 11 Javascript
预防网页挂马的方法总结
Nov 03 Javascript
通过命令行创建vue项目的方法
Jul 20 Javascript
node.js文件上传重命名以及移动位置的示例代码
Jan 19 Javascript
详解ES6系列之私有变量的实现
Nov 21 Javascript
如何使用three.js 制作一个三维的推箱子游戏
Jul 29 Javascript
js实现移动端图片滑块验证功能
Sep 29 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答题类应用接口实例
2015/02/09 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
PHP常用操作类之通信数据封装类的实现
2017/07/16 PHP
php多进程模拟并发事务产生的问题小结
2018/12/07 PHP
JavaScript作用域链示例分享
2014/05/27 Javascript
JSON.stringify转换JSON时日期时间不准确的解决方法
2014/08/08 Javascript
浅谈Javascript中的12种DOM节点类型
2016/08/19 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
JS实现类似51job上的地区选择效果示例
2016/11/17 Javascript
Bootstrap CSS组件之大屏幕展播
2016/12/17 Javascript
基于JS实现翻书效果的页面切换样式
2017/02/16 Javascript
jQuery实现图片滑动效果
2017/03/08 Javascript
详解Angular调试技巧之报错404(not found)
2018/01/31 Javascript
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
centos系统升级python 2.7.3
2014/07/03 Python
python简单实现计算过期时间的方法
2015/06/09 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
python中如何使用朴素贝叶斯算法
2017/04/06 Python
win10系统下Anaconda3安装配置方法图文教程
2018/09/19 Python
Django在pycharm下修改默认启动端口的方法
2019/07/26 Python
Ubuntu16.04安装python3.6.5步骤详解
2020/01/10 Python
Python基于类路径字符串获取静态属性
2020/03/12 Python
pandas apply使用多列计算生成新的列实现示例
2021/02/24 Python
门卫岗位安全职责
2013/12/13 职场文书
会计应聘求职信范文
2013/12/17 职场文书
优秀村官事迹材料
2014/01/10 职场文书
高一新生军训方案
2014/05/12 职场文书
2014幼儿教师个人工作总结
2014/12/03 职场文书
2014年电厂工作总结
2014/12/04 职场文书
国家助学贷款承诺书
2015/04/30 职场文书
学校百日安全活动总结
2015/05/07 职场文书
2016年春季运动会加油稿
2015/07/22 职场文书
九年级化学教学反思
2016/02/22 职场文书
Kubernetes中Deployment的升级与回滚
2022/04/01 Servers
详细介绍Next.js脚手架完整搭建封装
2022/04/26 Javascript