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 相关文章推荐
Javascript 判断 object 的特定类转载
Feb 01 Javascript
IE iframe的onload方法分析小结
Jan 07 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
Apr 13 Javascript
基于jQuery的获取标签名的代码
Jul 16 Javascript
JavaScript中的连字符详解
Nov 28 Javascript
基于jquery实现轮播焦点图插件
Mar 31 Javascript
javascript显示动态时间的方法汇总
Jul 06 Javascript
微信小程序表单弹窗实例
Jul 19 Javascript
中高级前端必须了解的JS中的内存管理(推荐)
Jul 04 Javascript
教你搭建按需加载的Vue组件库(小结)
Jul 29 Javascript
jquery实现垂直手风琴菜单
Mar 04 jQuery
《javascript设计模式》学习笔记一:Javascript面向对象程序设计对象成员的定义分析
Apr 07 Javascript
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多个文件上传到服务器实例
2014/10/29 PHP
php处理单文件、多文件上传代码分享
2016/08/24 PHP
PHP不使用递归的无限级分类简单实例
2016/11/05 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
JavaScript 学习初步 入门教程
2010/03/25 Javascript
Script的加载方法小结
2011/01/12 Javascript
js仿百度有啊通栏展示效果实现代码
2013/05/28 Javascript
javascript与css3动画结合使用小结
2015/03/11 Javascript
基于JS实现的倒计时程序实例
2015/07/24 Javascript
jQuery实现textarea自动增长宽高的方法
2015/12/18 Javascript
jQuery解决浏览器兼容性问题案例分析
2016/04/15 Javascript
JS实现超简单的汉字转拼音功能示例
2016/12/22 Javascript
微信小程序 setData使用方法及常用错误解决办法
2017/05/11 Javascript
angular中ui calendar的一些使用心得(推荐)
2017/11/03 Javascript
微信小程序实现YDUI的ScrollTab组件
2018/02/02 Javascript
vue2.0项目实现路由跳转的方法详解
2018/06/21 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
基于elementUI竖向表格、和并列的案例
2020/10/26 Javascript
解决vant的Toast组件时提示not defined的问题
2020/11/11 Javascript
[01:32]DOTA2上海特锦赛现场采访:最想COS的英雄
2016/03/25 DOTA
基于python3 OpenCV3实现静态图片人脸识别
2018/05/25 Python
Python 实现中值滤波、均值滤波的方法
2019/01/09 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
Python3读写ini配置文件的示例
2020/11/06 Python
凯蒂·佩里个人女鞋品牌:Katy Perry Collections
2019/04/04 全球购物
美国智能家居专家:tink
2019/06/04 全球购物
门卫人员岗位职责
2013/12/24 职场文书
研究生导师推荐信
2014/09/06 职场文书
2014和解协议书范文
2014/09/15 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
会议邀请函
2015/01/30 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
会议承办单位欢迎词
2015/09/30 职场文书
《火烧云》教学反思
2016/02/23 职场文书
python爬虫之利用selenium模块自动登录CSDN
2021/04/22 Python
Redis实战高并发之扣减库存项目
2022/04/14 Redis