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实现向右伸出的多级网页菜单效果
Aug 25 Javascript
javascript运动框架用法实例分析(实现放大与缩小效果)
Jan 08 Javascript
Javascript+CSS3实现进度条效果
Oct 28 Javascript
预防网页挂马的方法总结
Nov 03 Javascript
jquery Easyui Datagrid实现批量操作(编辑,删除,添加)
Feb 20 Javascript
form表单序列化详解(推荐)
Aug 15 Javascript
jquery实现图片跟随鼠标的实例
Oct 17 jQuery
解决vue 打包发布去#和页面空白的问题
Sep 04 Javascript
深入理解JS异步编程-Promise
Jun 03 Javascript
基于Bootstrap和JQuery实现动态打开和关闭tab页的实例代码
Jun 10 jQuery
layui表单验证select下拉框实现验证的方法
Sep 05 Javascript
vue+Element-ui实现分页效果
Nov 15 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脚本来实现WordPress中评论分页的功能
2015/12/10 PHP
php 获取文件行数的方法总结
2016/10/11 PHP
JQuery select标签操作代码段
2010/05/16 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
2012/12/25 Javascript
页面定时刷新(1秒刷新一次)
2013/11/22 Javascript
table对象中的insertRow与deleteRow使用示例
2014/01/26 Javascript
JS碰撞运动实现方法详解
2016/12/15 Javascript
详解基于webpack搭建react运行环境
2017/06/01 Javascript
JS简单添加元素新节点的方法示例
2018/02/10 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
vue+node实现图片上传及预览的示例方法
2018/11/22 Javascript
微信小程序-form表单提交代码实例
2019/04/29 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
[01:35]辉夜杯战队访谈宣传片—LGD
2015/12/25 DOTA
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
零基础写python爬虫之urllib2使用指南
2014/11/05 Python
Python中的random()方法的使用介绍
2015/05/15 Python
Python2.7读取PDF文件的方法示例
2017/07/13 Python
python更改已存在excel文件的方法
2018/05/03 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
python的等深分箱实例
2019/11/22 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
Finishline官网:美国一家领先的运动品牌鞋类、服装零售商
2016/07/20 全球购物
美国销售第一的智能手机和平板电脑保护壳:OtterBox
2017/12/21 全球购物
EJB与JAVA BEAN的区别
2016/08/29 面试题
毕业生简历自我评价范文
2014/04/09 职场文书
设备售后服务承诺书
2014/05/30 职场文书
个人股份转让协议书范本
2014/10/26 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
九寨沟导游词
2015/02/02 职场文书
雨中的树观后感
2015/06/03 职场文书
天堂的孩子观后感
2015/06/11 职场文书
Js类的构建与继承案例详解
2021/09/15 Javascript
天谕手游15杯全调酒配方和调酒券的获得方式
2022/04/06 其他游戏
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL