使用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 相关文章推荐
JS中的public和private对象,即static修饰符
Jan 18 Javascript
Javascript中匿名函数的多种调用方式总结
Dec 06 Javascript
浅析Javascript匿名函数与自执行函数
Feb 06 Javascript
基于WebUploader的文件上传js插件
Aug 19 Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
May 02 Javascript
最通俗易懂的javascript变量提升详解
Aug 05 Javascript
JS实现的DOM插入节点操作示例
Apr 04 Javascript
JS实现的判断方法、变量是否存在功能示例
Mar 28 Javascript
微信小程序自定义组件实现tabs选项卡功能
Jul 14 Javascript
解决vue-cli项目打包出现空白页和路径错误的问题
Sep 04 Javascript
浅析微信小程序modal弹窗关闭默认会执行cancel问题
Oct 14 Javascript
JavaScript计算出两个数的差值
Mar 19 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数组类型分析说明
2010/07/27 PHP
PHP5函数小全(分享)
2013/06/06 PHP
php中strstr、strrchr、substr、stristr四个函数的区别总结
2014/09/22 PHP
php mailer类调用远程SMTP服务器发送邮件实现方法
2016/03/04 PHP
YII Framework教程之异常处理详解
2016/03/14 PHP
PHP获取访问设备信息的方法示例
2019/02/20 PHP
JQuery 学习笔记 element属性控制
2009/07/23 Javascript
jquery显示和隐藏div特效实例
2013/02/27 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
JavaScript中创建类/对象的几种方法总结
2013/11/29 Javascript
在JS中如何调用JSP中的变量
2014/01/22 Javascript
AngularJS基础学习笔记之控制器
2015/05/10 Javascript
微信小程序 动态绑定事件并实现事件修改样式
2017/04/13 Javascript
NodeJS实现微信公众号关注后自动回复功能
2017/05/31 NodeJs
JS处理一些简单计算题
2018/02/24 Javascript
小程序兼容安卓和IOS数据处理问题及坑
2018/09/18 Javascript
爬虫利器Puppeteer实战
2019/01/09 Javascript
Javascript之高级数组API的使用实例
2019/03/08 Javascript
深入了解响应式React Native Echarts组件
2019/05/29 Javascript
Node.js使用MongoDB的ObjectId作为查询条件的方法
2019/09/10 Javascript
python itchat实现微信好友头像拼接图的示例代码
2017/08/14 Python
机器学习经典算法-logistic回归代码详解
2017/12/22 Python
Django中的Signal代码详解
2018/02/05 Python
Python计算一个点到所有点的欧式距离实现方法
2019/07/04 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
python opencv实现证件照换底功能
2019/08/19 Python
python3的数据类型及数据类型转换实例详解
2019/08/20 Python
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
执行力心得体会
2013/12/31 职场文书
领导干部作风建设自查报告
2014/10/23 职场文书
党的群众路线教育实践活动个人对照检查材料(校长)
2014/11/05 职场文书
药房管理制度范本
2015/08/06 职场文书
读《推着妈妈去旅行》有感1500字
2019/10/15 职场文书
PostgreSQL数据库去除重复数据和运算符的基本查询操作
2022/04/12 PostgreSQL
Python开发五子棋小游戏
2022/05/02 Python