uniapp使用Canvas实现电子签名

来源:

公司的一个需求,需要给新注册的会员和客商需要增加签署协议功能;

之前的思路:
1、使用vue-signature-pad来实现电子签名,但是安卓手机不兼容;
2、uniapp插件市场来实现,但是对HBuilderX的版本有要求,无奈公司只能使用3.4.7版本;

前面2种思路都不行那就用Canvas来实现

Canvass

canvas 是 html 的一个标签,它可以结合 JavaScript 提供的 canvasApi 来绘制各种各样的图形。canvas 主要用于绘制 2D 图形。注意:当你不设置 canvas 的宽高时,它的默认宽高是 300px、150px。

需要实现的功能如图:
在这里插入图片描述

代码实现

EctronicSignature.vue<template><view class="ectronic-signature"><canvasclass="board-canvas"canvas-id="drawCanvas"disable-scroll="true"@touchstart="touchStart"@touchmove="touchMove"@touchend="touchEnd"></canvas><view class="btn"><u-button type="success" @click="saveImage" text="保存" class="btnItem"></u-button><u-button @click="clearDrawBoard" text="清空" class="btnItem"></u-button></view></view>
</template><style lang="scss" scoped>
……
</style>
EctronicSignature.tscurDrawArr: any = [];startX: any = 0;startY: any = 0;ctx: any = {};begin: Boolean = false;bgColor: String = 'white'; //背景色lineWidth: Number = 4; //画笔宽度penMode: Boolean = true; //打开画笔  开关currentTab: any = 1;currentIndex: any = 0;selectPointer: any = []; //所有选中的线cache: any = '';points: any = [];onReady() {this.ctx = uni.createCanvasContext('drawCanvas', this); // 获取canvas上下文对象 vue的写法是先获取,之后通过.getContext("2d")来获取上下文this.cache = new Map(); // 缓存this.ctx.setLineWidth(this.lineWidth); // 设置画笔的粗细}// ctx.draw()绘制结果呈现在canvas// isReverse: 是否保留之前的像素draw(isReverse = false, cb) {this.ctx.draw(isReverse, () => {if (cb && typeof cb == 'function') {cb();}});}// 绘画 开始touchStart(e) {console.log('绘画开始', e.touches[0].x, e.touches[0].y);// customPrint('我能够进行绘制');if (this.penMode) {this.lineBegin(e.touches[0].x, e.touches[0].y);this.lineAddPoint(e.touches[0].x, e.touches[0].y);this.draw(true, ''); // 呈现画面}this.points.push([e.touches[0].x, e.touches[0].y]); // 存储绘制的点this.selectPointer.push([[e.touches[0].x, e.touches[0].y]]);}// 开始绘制线条lineBegin(x, y) {this.begin = true; // 作为一个标记代表开始绘画this.ctx.beginPath(); // 开始创建一个路径this.startX = x;this.startY = y;this.ctx.moveTo(this.startX, this.startY); // 将路径移动到画布中的指定点this.lineAddPoint(x, y); // 绘制线条中间添加}// 绘画 移动touchMove(e) {console.log('绘画移动', e.touches[0].x, e.touches[0].y);if (this.begin) {if (this.penMode) {this.lineAddPoint(e.touches[0].x, e.touches[0].y);this.draw(true, '');}this.points.push([e.touches[0].x, e.touches[0].y]);this.selectPointer[this.selectPointer.length - 1].push([e.touches[0].x, e.touches[0].y]);}}// 绘制线条中间添加点lineAddPoint(x, y) {this.ctx.moveTo(this.startX, this.startY);this.ctx.lineTo(x, y); // 增加一个新的点,然后创建一条从上次指定点到目标点的线this.ctx.stroke(); // 画出当前路径的边框this.startX = x;this.startY = y;}// 绘画 结束touchEnd(e) {if (this.penMode) {// this.curDrawArr = [];this.points = [];this.lineEnd();}}// 绘制线条结束lineEnd() {this.ctx.closePath(); // 关闭一个路径,关闭路径会连接起点和终点this.begin = false;}// 检验画布是否为空isCanvasBlank(canvas) {const blank = document.createElement('canvas'); //系统获取一个空canvas对象blank.width = canvas.width;blank.height = canvas.height;return canvas.toDataURL() == blank.toDataURL();  // .toDataURL()将canvas对象转换为base64位编码}// 保存 图片数据saveImage() {const _this = this;uni.canvasToTempFilePath({canvasId: 'drawCanvas',success: function(res) {console.log('res ==>', res);// 在H5平台下,tempFilePath 为 base64// this.uploadimage(res.tempFilePath,"save",page.currentTab)const canvas = document.getElementsByTagName('canvas')[0];if (_this.isCanvasBlank(canvas)) {uni.showToast({title: '请签字!!!',icon: 'none',});return false;}},});}//清除clearDrawBoard() {this.ctx.draw();this.selectPointer = [];}}

推荐资料

https://www.runoob.com/html/html5-canvas.html
https://uniapp.dcloud.net.cn/component/canvas.html#canvas
https://open.dingtalk.com/document/personalapp/setlinewidth

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/146010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MMC/SD/SDIO】读写操作

SD 总线是基于命令和数据流&#xff0c;它们由一个开始 Bit 发起&#xff0c;由一个停止 Bit 结束。 Command&#xff1a;命令开始一个操作。命令由 Host 驱动&#xff0c;或者给单卡&#xff08;寻址命令&#xff09;&#xff0c;或者给所有连接的卡&#xff08;广播命令&…

决策树的Boosting策略是什么

在决策树的Boosting策略中&#xff0c;最常见的算法是梯度提升决策树&#xff08;Gradient Boosting Decision Trees&#xff0c;简称GBDT&#xff09;。GBDT是一种集成学习方法&#xff0c;通过串行训练多个决策树&#xff0c;并根据前一个树的预测结果来调整下一个树的训练目…

【Linux网络】工作环境救急——关于yum安装的5个花式操作

目录 1、只下载不安装&#xff0c;离线安装软件 2、自行打包创建元数据 第一步&#xff1a;先准备好nginx的软件包&#xff0c;放在一个文件夹下 第二步&#xff1a;在本地下载createrepo命令软件&#xff0c;用于创建元信息&#xff0c;这个一定是对包的上一级目录使用命令…

无线WiFi安全渗透与攻防(六)之WEP破解-Gerix-wifi-cracker自动化破解WEP加密

WEP破解-Gerix-wifi-cracker自动化破解WEP加密 WEP破解-Gerix-wifi-cracker自动化破解WEP加密1.环境准备1.软件和kali2.下载软件,下载地址3.将软件复制到kali,解压4.进入软件目录2.破解步骤1.启动gerix-wifi-cracker-2-master软件2.设置无线网卡位Monitor Mode模式3.重新扫描…

【Python 千题 —— 基础篇】输出列表平均值

题目描述 题目描述 输出列表的平均值。题中有一个包含数字的列表 [19, 39, 130, 48, 392, 101, 92]&#xff0c;使用 for 循环输出这个列表中所有项的平均值。 输入描述 无输入。 输出描述 输出列表的平均值。 示例 示例 ① 输出&#xff1a; 列表的平均值是&#xf…

【Android】导入三方jar包/系统的framework.jar

1.Android.mk导包 1).jar包位置 与res和src同一级的libs中(没有就新建) 2).Android.mk文件 LOCAL_STATIC_ANDROID_LIBRARIES&#xff1a;android静态库&#xff0c;经常用于一些support的导包 LOCAL_JAVA_LIBRARIES&#xff1a;依赖的java库&#xff0c;一般为系统的jar…

【MySQL学习笔记-001】- 创建表、插入数据、查看数据库结构

创建employees表 当创建一个表时&#xff0c;需要指定表的名称和每个列的名称和数据类型。以下是一个示例SQL语句&#xff0c;用于创建一个名为"employees"的表&#xff0c;其中包含员工ID、姓名、职位和工资等列&#xff1a; CREATE TABLE employees (employee_id…

PCA降维Python demo

读这篇15年CVPR的文章&#x1f923;&#x1f923;&#x1f923;&#x1f923;&#x1f923; inproceedings{liu2015sparse,title{Sparse convolutional neural networks},author{Liu, Baoyuan and Wang, Min and Foroosh, Hassan and Tappen, Marshall and Pensky, Marianna},…

相机突然断电,保存的DAT视频文件如何修复

3-7 本文主要解决因相机突然断电导致拍摄的视频文件损坏的问题。 在平常使用相机拍摄视频&#xff0c;比如用单反相机、无人机拍摄视频的时候&#xff0c;如果电池突然断电&#xff0c;或者突然炸机了&#xff0c;就非常有可能会得到一个损坏的视频文件&#xff0c;比如会产生…

事务隔离级别和MVCC

1. 事务隔离级别和MVCC 1.1 事务并发执行时的一致性问题 &#xff08;1&#xff09;脏写 事务修改了另一个未提交事务修改过的数据&#xff1b; 这里的一致性是&#xff1a;假设每个事务都遵守将变量 x 和 y 始终设置为相同值&#xff0c;操作序列如下所示&#xff1a; T1…

【Vue配置项】 computed计算属性 | watch侦听属性

目录 前言 computed计算属性 什么是计算属性&#xff1f; Vue的原有属性是什么&#xff1f; 得到的全新的属性是什么&#xff1f; 计算属性怎么用&#xff1f; 计算属性的作用是什么&#xff1f; 为什么说代码执行率高了&#xff1f; computed计算属性中的this指向 co…

Express.js 与 Nest.js对比

Express.js 与 Nest.js对比 自从 Node.js 发布以来&#xff0c;Javascript 在后端领域的使用有所增加。由于 Node.js 的使用越来越多&#xff0c;每天都会有新的框架和工具发布。Express 和 Nest 是使用 Node.js 创建后端应用程序的最著名的框架之一&#xff0c;在本文中&…

【前段基础入门之】=>CSS3新特性 响应式布局

文章目录 概念媒体查询媒体类型媒体特性媒体运算符 概念 所谓对响应式布局方案的理解&#xff0c;众说纷纭&#xff0c;核心点就是同一套代码在不同尺度屏幕下的布局呈现方式的不同 社区中有很多人分享&#xff0c;并列出了多种实现响应式布局的方案&#xff0c;比如【 rem&…

基于ssm+vue员工工资管理系统

基于ssmvue员工工资管理系统 摘要 随着信息技术的不断发展&#xff0c;各行各业对于高效管理和利用数据的需求也日益增长。员工工资管理系统作为企业管理中的一个重要组成部分&#xff0c;对于实现工资信息的精确计算、及时发放和有效管理具有重要意义。本文基于SSM&#xff08…

消息中间件概述

概述 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件&#xff0c;如ActiveMQ、RabbitMQ&#xff0c;Kafka&#xff0c;还有阿里…

3. Spring源码篇之ComponentScan

简介 前面介绍了scanner可以扫描某个包路径下的所有bean&#xff0c;我们最常用的也是通过ComponentScan指定包路径去扫描&#xff0c;在SpringBoot中也是如此&#xff0c;本文将介绍spring扫描的逻辑 BeanDefinitionRegistryPostProcessor 知道了ComponentScan的作用&#…

Word文档处理:用Python轻松提取Word文档图文数据

将内容从Word文档中提取出来可以方便我们对其进行其他操作&#xff0c;如储将内容存在数据库中、将内容导入到其他程序中、用于AI训练以及制作其他文档等。使用Spire.Doc for Python提供了一个简单的方法直接提取Word文档中的文本内容&#xff0c;包括文本和图片&#xff0c;而…

Mybatisplus集成springboot完成分页查询

今天解决的是&#xff1a;Mybatisplus集成pringboot完成分页功能 &#x1f6f4;&#x1f6f4;&#x1f6f4; 之前一直用Pagehelper&#xff0c;迫于无奈pagehelper与springboot冲突太多&#xff0c;就改了MP自带的分页 &#x1f388;引入依赖 引入mybatisplus依赖 <depen…

【Linux】重定向|重新理解Linux下一切皆文件

文章目录 一、什么是重定向输出重定向的原理认识一下输出重定向的系统调用输出重定向的另外写法 二、浅谈输入重定向三、重定向和进程替换有冲突吗四、Linux下一切皆文件总结 一、什么是重定向 理解重定向之前&#xff1a;先理解一个叫做文件描述符的具体操作。 文件描述符&a…

【Qt之QWizardPage】使用

介绍 QWizardPage类是向导页面的基类。 QWizard表示一个向导。每个页面都是一个QWizardPage。当创建自己的向导时&#xff0c;可以直接使用QWizardPage&#xff0c;也可以子类化它以获得更多控制。 页面具有以下属性&#xff0c;由QWizard呈现&#xff1a;a title&#xff0c;…