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 相关文章推荐
禁止F5等快捷键的JS代码
Mar 06 Javascript
Javascript select下拉框操作常用方法
Nov 09 Javascript
node.js中的http.response.writeHead方法使用说明
Dec 14 Javascript
jQuery.Highcharts.js绘制柱状图饼状图曲线图
Mar 14 Javascript
用户代理字符串userAgent可实现的四个识别
Sep 20 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
Apr 08 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
Dec 19 Javascript
Angular2平滑升级到Angular4的步骤详解
Mar 29 Javascript
vue实现样式之间的切换及vue动态样式的实现方法
Dec 19 Javascript
Vue中props的使用详解
Jun 15 Javascript
微信小程序如何实现在线客服功能
Oct 16 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 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
shopex主机报错误请求解决方案(No such file or directory)
2011/12/27 PHP
php+croppic.js实现剪切上传图片功能
2018/08/14 PHP
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
鼠标滑上去后图片放大浮出效果的js代码
2011/05/28 Javascript
Javascript模块化编程(一)模块的写法最佳实践
2013/01/17 Javascript
require.js深入了解 require.js特性介绍
2014/09/04 Javascript
nodejs事件的监听与触发的理解分析
2015/02/12 NodeJs
jquery实现点击弹出带标题栏的弹出层(从右上角飞入)效果
2015/09/19 Javascript
js+canvas简单绘制圆圈的方法
2016/01/28 Javascript
jquery遍历table的tr获取td的值实现方法
2016/05/19 Javascript
jQuery移动端图片上传组件
2016/06/12 Javascript
BootStrap Select清除选中的状态恢复默认状态
2017/06/20 Javascript
vue router2.0二级路由的简单使用
2017/07/05 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
2017/07/27 Javascript
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
微信小程序封装多张图片上传api代码实例
2019/12/30 Javascript
解决Nuxt使用axios跨域问题
2020/07/06 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
JavaScript 异步时序问题
2020/11/20 Javascript
[54:15]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第二场2月1日
2021/03/11 DOTA
python逐行读取文件内容的三种方法
2014/01/20 Python
python显示天气预报
2014/03/02 Python
django2+uwsgi+nginx上线部署到服务器Ubuntu16.04
2018/06/26 Python
Python中is和==的区别详解
2018/11/15 Python
python地震数据可视化详解
2019/06/18 Python
关于Python中的向量相加和numpy中的向量相加效率对比
2019/08/26 Python
了解一下python内建模块collections
2020/09/07 Python
水上运动奥特莱斯:Wasterports Outlet
2018/08/08 全球购物
世界地球日活动总结
2015/02/09 职场文书
博物馆观后感
2015/06/05 职场文书
喋血孤城观后感
2015/06/08 职场文书
《观察物体》教学反思
2016/02/17 职场文书
导游词之山西-五老峰
2019/10/07 职场文书
导游词之无锡梅园
2019/11/28 职场文书