vue移动端使用canvas签名的实现


Posted in Javascript onJanuary 15, 2020

效果

vue移动端使用canvas签名的实现

canvas画板移动端 .gif

需求

  在一些项目业务中,经常会使用到画板,让用户自己去写/画一些东西做标示,比如说在线签电子合约、签名等,如果不用插件,那么如何使用h5的canvas画布来实现这一需求呢? 【本篇只讨论移动端,PC端请看上篇】

分析

  很明显,我们需要一个canvas,关于canvas的一些基本操作可以在w3school或者别的一些平台上熟悉一下,其实本例也是基础操作。本案例在vue中完成。(脱离vue也一样。)

  • 首先,需要一个canvas画布
  • 其次,考虑逻辑
  • 把逻辑实现

1. canvas画布

随意布局的一个画布,此处值得注意的是如果canvas的宽高确定,则在html>canvas中直接写宽高,如果不确定,根据别的元素变化,那么可以在js中初始化画布时写。

html

<div class="boardBox" ref="boardBox">
  <canvas ref="board"
      
  </canvas>
</div>

布局

.boardBox{
  margin: 30px auto;
  width: 90vw;
  height: 25vh;
  background: #f9f9f9;
  canvas{
    border: 1px solid #b3b3b3;
  }
}

画布初始化

let board = this.$refs.board;  // 获取DOM
board.width = this.$refs.boardBox.offsetWidth; // 设置画布宽
board.height = this.$refs.boardBox.offsetHeight;  // 设置画布高
this.ctx = board.getContext('2d');  // 二维绘图
this.ctx.strokeStyle = '#000';  // 颜色
this.ctx.lineWidth = 3; // 线条宽度

2. 逻辑分析

由于本篇只讨论移动端端,因此无非是在画布上监听三个触摸事件:touchstart、touchmove、touchend。
那么,在这三个事件中,分别需要做什么呢?

touchstart

开始滑动按下,需要做:

  • 获取触摸点做画布上的位置
  • 存为一个点坐标(起始点)
  • 以起始点建立一个路径
  • 开启画布操作

touchmove

触摸滑动时,又要做那些准备呢?

  • 判断是否开启画布操作,如果没开启就禁止绘制,因此先判断是否当前状态可绘制
  • 获取触摸点做画布上的位置
  • 上一个点到这一个点作连线
  • 绘制出来
  • 当前点存储,下一次用

touchend

滑动结束,事件结束:

  • closePath() // 停止绘制
  • 关闭画布操作的开关

好了,其实就是这三个事件,理清楚之后去代码实现就简单得多了。附上代码一份。

3. 代码

CSS略,如初始化即可,不是重点。

<div class="boardBox" ref="boardBox">
  <canvas ref="board"
      @touchstart="mStart"
      @touchmove="mMove"
      @touchend="mEnd">
  </canvas>
</div>
data() {
  return {
    ctx: null,
    point: {
      x: 0,
      y: 0
    },
    moving: false  // 是否正在绘制中且移动
  };
},
mounted() {
  let board = this.$refs.board;  // 获取DOM
  board.width = this.$refs.boardBox.offsetWidth; // 设置画布宽
  board.height = this.$refs.boardBox.offsetHeight;  // 设置画布高
  this.ctx = board.getContext('2d');  // 二维绘图
  this.ctx.strokeStyle = '#000';  // 颜色
  this.ctx.lineWidth = 3; // 线条宽度
},
methods: {
  // 触摸(开始)
  mStart (e) {
    console.log(e);
    let x = e.touches[0].clientX - e.target.offsetLeft,
      y = e.touches[0].clientY - e.target.offsetTop;  // 获取触摸点在画板(canvas)的坐标
    this.point.x = x;
    this.point.y = y;
    this.ctx.beginPath();
    this.moving = true;
  },
  // 滑动中...
  mMove (e) {
    if(this.moving) {
      let x = e.touches[0].clientX - e.target.offsetLeft,
        y = e.touches[0].clientY - e.target.offsetTop;  // 获取触摸点在画板(canvas)的坐标
      this.ctx.moveTo(this.point.x, this.point.y);  // 把路径移动到画布中的指定点,不创建线条(起始点)
      this.ctx.lineTo(x, y); // 添加一个新点,然后创建从该点到画布中最后指定点的线条,不创建线条
      this.ctx.stroke(); // 绘制
      this.point.x = x, this.point.y = y;  // 重置点坐标为上一个坐标
    }
  },
  // 滑动结束
  mEnd () {
    if(this.moving) {
      this.ctx.closePath();  // 停止绘制
      this.moving = false;  // 关闭绘制开关
    }
  },
},

思考

  1. 上一篇,在PC端完成绘制,本篇如法炮制,在移动端也顺利完成,相比pc端只是稍微的修改了一下获取坐标点的算法而已。那么PC端和移动端如何并存呢?
  2. 出错了,怎么重新绘制呢?
  3. 绘制完成后,怎么保存呢?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery select(列表)的操作(取值/赋值)
Aug 06 Javascript
jQuery对象与DOM对象之间的转换方法
Apr 15 Javascript
JavaScript常用对象的方法和属性小结
Jan 24 Javascript
JavaScript各类型的关系图解
Oct 16 Javascript
学习JavaScript正则表达式
Nov 13 Javascript
浅谈javascript中的constructor
Jun 08 Javascript
javascript 内置对象及常见API详细介绍
Nov 01 Javascript
微信小程序实现长按删除图片的示例
May 18 Javascript
修改vue+webpack run build的路径方法
Sep 01 Javascript
微信小程序出现wx.getLocation再次授权问题的解决方法分析
Jan 16 Javascript
layui表格分页 记录勾选的实例
Sep 02 Javascript
Vue中使用wangeditor富文本编辑的问题
Feb 07 Vue.js
js实现鼠标拖拽div左右滑动
Jan 15 #Javascript
Vue数字输入框组件示例代码详解
Jan 15 #Javascript
Vue v-bind动态绑定class实例方法
Jan 15 #Javascript
JS 事件机制完整示例分析
Jan 15 #Javascript
JS实现滑动插件
Jan 15 #Javascript
JS实现滑动导航效果
Jan 14 #Javascript
解决 window.onload 被覆盖的问题方法
Jan 14 #Javascript
You might like
PHP 出现乱码和Sessions验证问题的解决方法!
2008/12/06 PHP
关于php循环跳出的问题
2013/07/01 PHP
PHP引用的调用方法分析
2016/04/25 PHP
PHP实现微信小程序用户授权的工具类示例
2019/03/05 PHP
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
用jquery修复在iframe下的页面锚点失效问题
2014/08/22 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
移动适配的几种方案(三种方案)
2016/11/25 Javascript
基于node.js依赖express解析post请求四种数据格式
2017/02/13 Javascript
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
bootstrap table支持高度百分比的实例代码
2018/02/28 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
深入理解react-router 路由的实现原理
2018/09/26 Javascript
js点击事件的执行过程实例分析【冒泡与捕获】
2020/04/11 Javascript
[54:24]Optic vs TNC 2018国际邀请赛小组赛BO2 第二场
2018/08/18 DOTA
理解python多线程(python多线程简明教程)
2014/06/09 Python
Python实现 版本号对比功能的实例代码
2019/04/18 Python
pyqt5 comboBox获得下标、文本和事件选中函数的方法
2019/06/14 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
详解使用python绘制混淆矩阵(confusion_matrix)
2019/07/14 Python
Python操作远程服务器 paramiko模块详细介绍
2019/08/07 Python
Python Web静态服务器非堵塞模式实现方法示例
2019/11/21 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
2020/06/30 Python
python使用ctypes库调用DLL动态链接库
2020/10/22 Python
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
丹尼尔惠灵顿手表天猫官方旗舰店:Daniel Wellington
2017/08/25 全球购物
Trina Turk官网:美国时装和泳装品牌
2018/06/10 全球购物
Java面试题:说出如下代码的执行结果
2015/10/30 面试题
电子商务毕业生求职信
2013/11/10 职场文书
岗位竞聘演讲稿
2014/01/10 职场文书
十佳文明家庭事迹
2014/05/25 职场文书
教师个人成长总结
2015/02/11 职场文书
郭明义电影观后感
2015/06/08 职场文书
结婚司仪主持词
2015/06/29 职场文书
Java网络编程之UDP实现原理解析
2021/09/04 Java/Android