使用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 相关文章推荐
页面中body onload 和 window.onload 冲突的问题的解决
Jul 01 Javascript
JS原型对象通俗&quot;唱法&quot;
Dec 27 Javascript
javascript实现table表格隔行变色的方法
May 13 Javascript
详解javascript的变量与标识符
Jan 04 Javascript
JS键盘版计算器的制作方法
Dec 03 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
Dec 08 Javascript
javascript实现用户点击数量统计
Dec 25 Javascript
Vue.js 2.0中select级联下拉框实例
Mar 06 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
Apr 26 Javascript
深入了解JavaScript 私有化
May 30 Javascript
在vue+element ui框架里实现lodash的debounce防抖
Nov 13 Javascript
关于JavaScript 中 if包含逗号表达式
Nov 27 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
PHP4 与 MySQL 交互使用
2006/10/09 PHP
PHP时间戳 strtotime()使用方法和技巧
2013/10/29 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
PHP读取RSS(Feed)简单实例
2014/06/12 PHP
smarty内置函数{loteral}、{ldelim}和{rdelim}用法实例
2015/01/22 PHP
php创建、获取cookie及基础要点分析
2015/01/26 PHP
PHP针对多用户实现更换头像功能
2016/09/04 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
用js实现的自定义的对话框的实现代码
2010/03/21 Javascript
jquery统计复选框选中示例
2013/11/05 Javascript
Node.js实现简单聊天服务器
2014/06/20 Javascript
JS集成fckeditor及判断内容是否为空的方法
2016/05/27 Javascript
BootstrapValidator实现注册校验和登录错误提示效果
2017/03/10 Javascript
JavaScript实现短信倒计时60s
2017/10/09 Javascript
Vue中之nextTick函数源码分析详解
2017/10/17 Javascript
分享ES6的7个实用技巧
2018/01/18 Javascript
详解如何在nuxt中添加proxyTable代理
2018/08/10 Javascript
vue.js多页面开发环境搭建过程
2019/04/24 Javascript
vue如何截取字符串
2019/05/06 Javascript
Vue.js实现大转盘抽奖总结及实现思路
2019/10/09 Javascript
Vue插件之滑动验证码用法详解
2020/04/05 Javascript
Python函数学习笔记
2008/10/07 Python
python实现TCP服务器端与客户端的方法详解
2015/04/30 Python
Python利用前序和中序遍历结果重建二叉树的方法
2016/04/27 Python
Django查询数据库的性能优化示例代码
2017/09/24 Python
使用Python进行体育竞技分析(预测球队成绩)
2019/05/16 Python
python sqlite的Row对象操作示例
2019/09/11 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
Python实现粒子群算法的示例
2021/02/14 Python
DVF官方网站:美国时装界尊尚品牌
2017/08/29 全球购物
美国最大的袜子制造商和零售商:Renfro Socks
2017/09/03 全球购物
普师专业个人自荐信范文
2013/11/26 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
中秋节晚会开场白
2015/05/29 职场文书
2019年公司快递收发管理制度模板
2019/11/20 职场文书
Redis基于Bitmap实现用户签到功能
2021/06/20 Redis