前言

实现签名的功能听着很复杂,其实很简单。使用canvas辅助的API和监听鼠标相关事件即可实现。

思考:

1、如何使用canvas画线 ?

2、如何判断在提交签名时判断是否有签名 ?

3、如何将canvas 转成的base64转成File文件对象传给后端 ?

Canvas的一些api介绍

1. 绘制直线

ctx.strokeStyle = "#000"  // 设置线条颜色
ctx.lineWidth = 2    // 设置线条宽度
ctx.beginPath()      // 开始绘图路径
ctx.moveTo(x, y)     // 将输入的坐标移动至直线起点
ctx.lineTo(x, y)     // 绘制直线到输入的坐标
ctx.stroke()         // 绘制图形的边界轮廓
ctx.closePath()      // 闭合绘图路径

2. ctx.toDataURL() 用于将canvas对象转换为base64编码

toDataURL接收两个参数
toDataURL(type, encoderOptions)
type :指定转换为base64编码后的图片的格式,如image/png、image/jpeg、image/webp等等,默认为image/png格式;
encoderOptions:用于设置转换为base64编码后图片的质量,取值范围0-1

3. ctx.clearRect() 方法清空给定矩形内的指定像素

ctx.clearRect(x, y, width, height)
x:要清除的矩形左上角的x坐标
y:要清除的矩形左上角的y坐标
width:要清除的矩形的宽度,以像素计
height:要清除的矩形的高度,以像素计

实现

  • 定义一个points变量存放画线的坐标,我这边是如果坐标数量大于20个则表示有签名痕迹
  • 监听鼠标按下事件时,记录起始位置,开启绘画状态
  • 监听鼠标移动事件时,记录移动位置,开始画线,记录画线的坐标
  • 监听鼠标松开事件时,更改绘画状态

全部的代码实现

<template><div class="autographView"><div class="header"><span style="margin-right:20px">电子签名</span><a-icon type="edit" /></div><div class="autograph_container" ref="autographContainer"><canvas ref="canvasRef"@mousedown="mousedown"@mousemove="mousemove"@mouseup="mouseup"></canvas></div><div class="autograph_btn"><div style="margin-right: 30px;"><a-button class="confirm-btn" icon="check" block @click="handleCommit">确定</a-button></div><div><a-button class="close-btn" icon="close" block @click="handleClear">清除</a-button></div></div></div>
</template>
<script>
export default {name: 'autographView',data () {return {ctx: null, // 存储canvasisPrint: false,strokeStyle: '#000', // 线条颜色lineWidth: 2, // 线条粗细startX: 0, // 记录起始x轴位置startY: 0, // 记录起始Y轴位置points: [] // 记录坐标 用来判断是否有签名的}},mounted () {this.initCanvas()},methods: {initCanvas () {// 获取父元素的宽高const { width, height } = this.$refs.autographContainer.getBoundingClientRect()const canvas = this.$refs.canvasRefcanvas.width = width // 设置canvas的宽canvas.height = height // 设置canvas的高// 获取2d画布上的上下文,所有的图形绘制都可以通过ctx的属性和方法来完成this.ctx = canvas.getContext('2d')},// 监听鼠标按下事件mousedown (event) {event.preventDefault()// 获取鼠标按下的基于offsetParent的位置this.startX = event.offsetXthis.startY = event.offsetYthis.isPrint = true // 开启绘画状态},// 监听鼠标移动mousemove (event) {event.preventDefault()// 要判断是否是开启了绘画状态if (!this.isPrint) returnconst obj = {x: event.offsetX,y: event.offsetY}// 设置线条颜色this.ctx.strokeStyle = this.strokeStyle// 设置线条宽度this.ctx.lineWidth = this.lineWidth// 开始描绘路径this.ctx.beginPath()// 将鼠标按下时记录的起始坐标移至直线起点this.ctx.moveTo(this.startX, this.startY)// 定义线条结束坐标this.ctx.lineTo(obj.x, obj.y)// 绘制图形的线条this.ctx.stroke()// 闭合绘图路径this.ctx.closePath()// 更新起始位置this.startX = obj.xthis.startY = obj.y// 记录坐标this.points.push(obj)},// 监听鼠标松开事件mouseup () {// 更改绘画状态this.isPrint = false},// 清除handleClear () {// clearRect() 方法清空给定矩形内的指定像素const { width, height } = this.$refs.canvasRefthis.ctx.clearRect(0, 0, width, height)// 清空坐标this.points = []},// 提交handleCommit () {// 判断至少有20个坐标 才算有签名if (this.points.length < 20) {this.$message.error('签名不能为空!')return}// 转成base64const baseFile = this.$refs.canvasRef.toDataURL() // 默认转成png格式的图片编码const filename = Date.now() // 用时间戳做文件名吧const file = this.dataURLToFile(baseFile, filename) // 图片文件形式 传给后端存储即可console.log('====>', file)},// 将base64转成File文件对象dataURLToFile (dataURL, filename) {const arr = dataURL.split(',')// 获取图片格式const imgType = arr[0].match(/:(.*?);/)[1]// atob() 方法用于解码使用 base-64 编码的字符串const dec = atob(arr[1])let n = dec.lengthconst u8arr = new Uint8Array(n)while (n--) {// 转成ASCII码u8arr[n] = dec.charCodeAt(n)}return new File([u8arr], filename, { type: imgType })}}
}
</script>

打印的file对象长这样

~~~ end ~~~

Vue—使用canvas实现电子签名相关推荐

  1. 使用vue造个小轮子vue-asign,canvas生成电子签名,满足需求

    优化需求,内容是生成电子签名,发现好多个项目都重复写,于是打算自己造个小轮子,名字就叫vue-asign,说明文档如下: vue-asign Canvas 生成电子签名 支持vue2.vue3 演示d ...

  2. 手机端canvas实现电子签名

    前言: 在上一篇文章中讲到了如何使用canvas在PC端实现电子签名,下面我们稍微修改一下代码在h5端也可以实现 效果图: 实现思路: 使用canvas来实现手写签名的功能,然后将canvas转化为图 ...

  3. vue中canvas签名

    vue用canvas横屏签名 最近遇到一个签名需求由于canvas一些特性,横屏签名不好控制,也是多方借鉴才解决,写真就是为了记录下,方便有需要的同学. js代码如下: import Draw fro ...

  4. Vue利用Canvas实现逐帧播放图片不闪烁(Vue解决逐帧播放图片闪烁问题)

    Vue利用Canvas实现逐帧播放图片不闪烁 前言 Vue代码实现 实现效果 前言 Vue采用<el-image :src="src"></el-image> ...

  5. vue实现canvas电子签名

    1,当前代码是本人亲自一行行敲出来的哦 <template><div style="margin-left: 28%;"><!-- 画布对象 --&g ...

  6. vue使用canvas实现手写电子签名;vue使用vue-esign插件实现手写电子签名;H5使用画布签名

    功能: 1.兼容 PC 和 Mobile: 2.画布自适应屏幕大小变化(窗口缩放.屏幕旋转时画布无需重置,自动校正坐标偏移): 3.自定义画布尺寸(导出图尺寸),画笔粗细.颜色,画布背景色: 4.支持 ...

  7. vue中用canvas实现移动端手写板、电子签名功能

    html部分: js部分: css部分:

  8. vue 打印 canvas 显示空白

    最近在弄 vue + elemnet 打印报表,然后有个需求就是直接打印将 echarts 表 也打印出来,我下载上打印插件后,在打印页面发现 echarts 图表部分为空白,再仔细检查发现这个插件不 ...

  9. app canvas渲染后图片黑色_H5 基于 canvas 实现电子签名并生成PDF文档

    (给前端大全加星标,提升前端技能) 转自:coyota666 https://juejin.cn/post/6901273585428463624 前言 电子签名通俗来说就是通过技术手段实现在电子文档 ...

最新文章

  1. 从搞笑到高效,构建敏捷团队的基础原则
  2. tensorflow2 存取模型_思维导图:长短期记忆模型
  3. 010 Editor v8.0.1_x32分析以及注册机制作
  4. android n 更新画面,Android N的无缝更新是什么?
  5. 2005年博客发展十大悬疑
  6. 社交网络图中结点的“重要性”计算
  7. 生成介于0.95-1的随机数MATLAB,matlab生成随机数函数
  8. laravel并行访问MySQL_laravel实现多数据库连接配置
  9. Nginx + PHP + mysql CGI的一个可能的安全漏洞
  10. 利用google工具进行关键词研究
  11. shopex网店系统数据库安装失败解决方法
  12. 数据库学习整理之常见运算符
  13. 支付宝小程序获取手机号授权
  14. 阿里云服务器安装code-server实现ipad编程、浏览器编程
  15. Json-Handle插件下载安装使用
  16. phpmyadmin 下载、安装、配置
  17. 解决Vscode提示code安装似乎损坏
  18. fft算法c语言复数结果是啥,算法-为什么FFT产生复数而不是实数?
  19. c++(标准模板库STL)
  20. 【C语言】用回调函数实现冒泡排序

热门文章

  1. 股市的起源发展和意义
  2. 如何快速自动填充空白单元格上一行的内容
  3. rror: [$injector:unpr] http...r?p0=contentCategoryServicePro错误解决方案
  4. MIoU(均交并比)的计算
  5. VS2015生成的exe文件在其他电脑下运行
  6. Leetcode 14.最长公共前缀(Longest Common Prefix)
  7. mpls 笔记 part 1
  8. jovi语音助手安装包_vivoJovi语音助手v3.1.1.0 Android
  9. WPF 几何图形之图形微语言命令
  10. Swoole 基础入门