使用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 相关文章推荐
List Installed Software Features
Jun 11 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
Apr 12 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
Jun 16 Javascript
浅谈js script标签中的预解析
Dec 30 Javascript
vue-devtools的安装步骤
Apr 23 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
Jan 24 Javascript
9102了,你还不会移动端真机调试吗
Mar 25 Javascript
详解JS实现简单的时分秒倒计时代码
Apr 25 Javascript
WebSocket的简单介绍及应用
May 23 Javascript
JavaScript静态作用域和动态作用域实例详解
Jun 17 Javascript
vue项目初始化到登录login页面的示例
Oct 31 Javascript
微信小程序连接服务器展示MQTT数据信息的实现
Jul 14 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的array数组和使用实例简明教程(容易理解)
2014/03/20 PHP
php创建session的方法实例详解
2015/01/27 PHP
php实现session自定义会话处理器的方法
2015/01/27 PHP
javascript Array.prototype.slice使用说明
2010/10/11 Javascript
幻灯片带网页设计中的20个奇妙应用示例小结
2012/05/27 Javascript
JS操作图片(增,删,改) 例子
2013/04/17 Javascript
深入浅析AngularJS中的module(模块)
2016/01/04 Javascript
JavaScript电子时钟倒计时
2016/01/09 Javascript
VUEJS实战之修复错误并且美化时间(2)
2016/06/13 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
将form表单通过ajax实现无刷新提交的简单实例
2016/10/12 Javascript
axios中cookie跨域及相关配置示例详解
2017/12/20 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
如何通过shell脚本自动生成vue文件详解
2019/09/10 Javascript
javascript实现数字时钟效果
2021/02/06 Javascript
[43:35]EG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Windows下PyMongo下载及安装教程
2015/04/27 Python
Python MySQLdb Linux下安装笔记
2015/05/09 Python
Python使用CMD模块更优雅的运行脚本
2015/05/11 Python
python字符串str和字节数组相互转化方法
2017/03/18 Python
Python开发的十个小贴士和技巧及长常犯错误
2018/09/27 Python
Python实现TCP通信的示例代码
2019/09/09 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
使用Python合成图片的实现代码(图片添加个性化文本,图片上叠加其他图片)
2020/04/30 Python
CSS3中使用RGBA设置透明度的示例
2015/08/04 HTML / CSS
canvas实现飞机打怪兽射击小游戏的示例代码
2018/07/09 HTML / CSS
英国领先的电视购物零售商:Ideal World
2019/03/18 全球购物
什么时候用assert
2015/05/08 面试题
企业为何需要商业计划书
2013/12/26 职场文书
小学生评语集锦
2014/04/18 职场文书
关于责任的演讲稿
2014/05/20 职场文书
羽毛球社团活动总结
2014/06/27 职场文书
社保缴纳证明申请书
2014/11/03 职场文书
简单的辞职信模板
2015/05/12 职场文书
七年级作文之《我和我的祖国》观后感作文
2019/10/18 职场文书
Redis中缓存穿透/击穿/雪崩问题和解决方法
2021/12/04 Redis