使用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参数的小问题
Mar 02 Javascript
input输入框鼠标焦点提示信息
Mar 17 Javascript
JavaScript高级教程5.6之基本包装类型(详细)
Nov 23 Javascript
js判断上传文件后缀名是否合法
Jan 28 Javascript
Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
Jun 21 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
Aug 24 Javascript
jquery实现的回旋滚动效果完整实例【附demo源码下载】
Sep 20 Javascript
jQuery实现两个select控件的互移操作
Dec 22 Javascript
JavaScript中双符号的运算详解
Mar 12 Javascript
在HTML文档中嵌入JavaScript的四种方法
May 07 Javascript
微信小程序引入VANT组件的方法步骤
Sep 19 Javascript
Vuex中实现数据状态查询与更改
Nov 08 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 保留小数点
2009/04/21 PHP
php等比例缩放图片及剪切图片代码分享
2016/02/13 PHP
function, new function, new Function之间的区别
2007/03/08 Javascript
js innerHTML 的一些问题的解决方法
2008/06/22 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
如何理解Vue的.sync修饰符的使用
2017/08/17 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
详解vue的数据劫持以及操作数组的坑
2019/04/18 Javascript
nodejs实现用户登录路由功能
2019/05/22 NodeJs
Javascript三种字符串连接方式及性能比较
2019/05/28 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
2019/08/20 Javascript
卸载vue2.0并升级vue_cli3.0的实例讲解
2020/02/16 Javascript
基于JS实现视频上传显示进度条
2020/05/12 Javascript
[57:47]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python datetime时间格式化去掉前导0
2014/07/31 Python
零基础写python爬虫之抓取百度贴吧并存储到本地txt文件改进版
2014/11/06 Python
列举Python中吸引人的一些特性
2015/04/09 Python
浅谈Python中的数据类型
2015/05/05 Python
Python中装饰器兼容加括号和不加括号的写法详解
2017/07/05 Python
python实现机械分词之逆向最大匹配算法代码示例
2017/12/13 Python
浅谈Python中的私有变量
2018/02/28 Python
浅谈Django的缓存机制
2018/08/23 Python
8种用Python实现线性回归的方法对比详解
2019/07/10 Python
django重新生成数据库中的某张表方法
2019/08/28 Python
Python imageio读取视频并进行编解码详解
2019/12/10 Python
Python enumerate内置库用法解析
2020/02/24 Python
阿迪达斯西班牙官方网站:adidas西班牙
2016/07/21 全球购物
护理工作感言
2014/01/16 职场文书
干部现实表现材料
2014/02/13 职场文书
共产党员承诺书
2014/03/25 职场文书
小兵张嘎观后感
2015/06/03 职场文书
新学期开学标语2015
2015/07/16 职场文书
2015年政教主任工作总结
2015/07/23 职场文书
导游词之天下银坑景区
2019/11/21 职场文书
如何理解PHP核心特性命名空间
2021/05/28 PHP
学习nginx基础知识
2021/09/04 Servers