基于uni-app的小程序电子签名功能(带有笔锋)

news2024/12/26 10:58:57

前言

目前做的一个项目需要用到电子签名的功能,网上其实也挺多这种类型的电子签名,但是带有笔锋效果的确比较少,所以参考了一些博客,总结成了这个功能,在此分享给大家。



效果展示

在这里插入图片描述



代码展示

触摸开始(touchstart)

touchstart(e) {
	if (!this.isInit) {
		this.isInit = true
		this.autographClick(1);
	}
	let startX = e.changedTouches[0].x
	let startY = e.changedTouches[0].y
	let startPoint = {
		X: startX,
		Y: startY
	}
	this.points.push(startPoint)

	//每次触摸开始,开启新的路径
	// console.log(this.points, "point11")
	this.canvasCtx.beginPath()
}

获取最开始的坐标,x和y,然后将他们存起来,注意每次触摸后都应该调用 beginPath()


触摸移动(touchmove)

touchmove(e) {
	let moveX = e.changedTouches[0].x
	let moveY = e.changedTouches[0].y
				
	let movePoint = {
		X: moveX,
		Y: moveY,
		T: new Date().getTime(),
		W: (MAX_LINE_WIDTH + MIN_LINE_WIDTH) / 2
	}

	this.points.push(movePoint) //存点

	if (lastPoint) {
		// console.log(lastPoint.T, movePoint.T)
		movePoint.W = this.calcLineWidth(movePoint); // 重新赋值宽度,覆盖默认值 
		this.canvasCtx.beginPath();
		this.canvasCtx.strokeStyle = '#000';
		this.canvasCtx.lineCap = 'round';
		this.canvasCtx.lineJoin = 'round';
		this.canvasCtx.lineWidth = movePoint.W;
		this.canvasCtx.moveTo(lastPoint.X, lastPoint.Y);
		this.canvasCtx.lineTo(movePoint.X, movePoint.Y);
		this.canvasCtx.stroke();
	}
	lastPoint = movePoint; // 结束前保存当前点为上一点
	
	let len = this.points.length
	if (len >= 2) {
		this.draw() //绘制路径
	}

}
				

获取移动的坐标,将坐标、时间和画笔宽度进行存点。


笔锋效果(calcLineWidth)

const MAX_V = 1; // 最大书写速度
const MIN_V = 0; // 最小书写速度
const MAX_LINE_WIDTH = 16; // 最大笔画宽度
const MIN_LINE_WIDTH = 4; // 最小笔画宽度
const MAX_LINE_DIFF = .03; // 两点之间笔画宽度最大差异
let context = null; // canvas上下文
let lastPoint = null; // 包含上一点笔画信息的对象


calcLineWidth(movePoint) {
	let consuming = movePoint.T - lastPoint.T; // 两点之间耗时
	if (!consuming) return lastPoint.W; // 如果当前点用时为0,返回上点的宽度。
	
	// 当前点的最大宽度
	let maxWidth = Math.min(MAX_LINE_WIDTH, lastPoint.W * (1 + MAX_LINE_DIFF)); 
	// 当前点的最小宽度,变细时速度快所以宽度变化要稍快
	let minWidth = Math.max(MIN_LINE_WIDTH, lastPoint.W * (1 - MAX_LINE_DIFF * 3)); 
	// 两点之间距离
	let distance = Math.sqrt(Math.pow(movePoint.X - lastPoint.X, 2) + Math.pow(movePoint.Y - lastPoint.Y, 2)); 
	/*当前点速度*/
	let speed = Math.max(Math.min(distance / consuming, MAX_V), MIN_V); 
	/* 当前点宽度 */
	let lineWidth = Math.max(Math.min(MAX_LINE_WIDTH * (1 - speed / MAX_V), maxWidth), minWidth); 

	return lineWidth;
}

在绘制的过程,通过两点之间的距离、速度计算出宽度,再进行绘制,也就是笔锋的效果。可以自己调节初始值,设置成自己最想要的效果。


绘制笔迹(draw)

draw() {
	let point1 = this.points[0]
	let point2 = this.points[1]
	this.points.shift()
	this.canvasCtx.moveTo(point1.X, point1.Y)
	this.canvasCtx.lineTo(point2.X, point2.Y)
	this.canvasCtx.stroke()
	this.canvasCtx.draw(true)
	this.hasSign = true
}
  1. 为保证笔迹实时显示,必须在移动的同时绘制笔迹;
  2. 为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo);
  3. 将上一次的终点作为下一次绘制的起点(即清除第一个点)。

触摸结束(touchend)

touchend() {
	this.points = []
	this.canvasCtx.draw(true)
	lastPoint = null;
}

最后别忘记再每次结束时,要进行清空。



总结

总体来说,虽然达到了效果,但是可能运行不是特别流畅,没有达到商业级的效果,还有待加强,大家可以提出自己的见解,我会参考并完善。

代码地址:https://gitee.com/Robergean/Signature

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

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

相关文章

大数据专业需要学习python么

如果零基础入门数据开发行业的小伙伴,可以从Python语言入手。 Python语言简单易懂,适合零基础入门,在编程语言排名上升最快,能完成数据挖掘、机器学习、实时计算在内的各种大数据集成任务。 但是不会python也是没有关系的&#…

基于Vector VT系统的车身域测试方案介绍

车身域控制器作为车身主要部件的控制大脑,需要经过严苛的测试,常见的测试方式是通过搭建硬件在环测试系统实现的,测试原理是通过仿真控制器外围的传感器和执行器,实现车身域控制器的闭环仿真和测试。小怿基于国际一流的测试设备提…

Day15 C++STL入门基础知识九——list容器 基本概念-构造函数-赋值变换-大小操作-插入删除-数据存取-反转排序 【全面深度剖析+例题代码展示】

文章目录1. 基本概念1.1 功能1.2 概念1.3 组成和存储方式1.4 优缺点1.4 图解2. 构造函数2.1 函数原型2.2 代码展示2.3 测试结果3. 赋值交换3.1 函数原型3.2 代码展示3.3 测试结果4. 大小操作1.3 代码展示1.4 测试结果6. 插入删除6.1 函数原型6.2 代码展示6.3 测试结果7. 数据存…

React报错#310复盘小结

React报错#310复盘小结问题背景解决方案原理&学习引发错误情况1. 不要在循环,条件或嵌套函数中调用 Hook2. 把所有的钩子移到组件的顶层,在任何可能返回值的条件之上。总结问题背景 apm报错:Minified React error #310 https://reactjs.…

浅谈Graph Embedding(一)

Graph Embedding算法背景引入先回顾下图的概念:图(graph)由节点(vertex)和点之间连线(edge)所组成;其中,点通常被成为“顶点(vertex)”,而点与点之间的连线则被成为“边”(edge)。通常记为,G(V,E)。常见分为无向图和有向图。示例如下&#xf…

MySQL数据类型约束

文章目录数据类型MySQL中的数据类型整数类型类型介绍可选属性MUNSIGNEDZEROFILL适用场景如何选择?浮点类型类型介绍数据精度说明精度误差说明定点数类型类型介绍开发中经验位类型:BIT6. 日期与时间类型YEAR类型DATE类型TIME类型DATETIME类型TIMESTAMP类型…

小白入门pwn笔记 CPU与进程的执行

1.回顾存储在磁盘中的叫节,映射到内存的时候叫段。内存中的节根据读写执行的权限不同在内存中映像为不同的段。段视图用于进程的内存区域的rwx权限划分。节视图用于ELF文件编译链接时与在磁盘上储存时的文件结构的组织。2.代码在内存重的映射关系不可写的数据一般会…

Qt OpenGL(三十六)——Qt OpenGL 核心模式-绘制雷达坐标系

提示:本系列文章的索引目录在下面文章的链接里(点击下面可以跳转查看): Qt OpenGL 核心模式版本文章目录 Qt OpenGL(三十六)——Qt OpenGL 核心模式-绘制雷达坐标系 一、场景 在日常的项目中,我们很多时候会遇到,绘制雷达扫描图的情况,比如,你的项目是给下面的雷达…

unidbg-boot-server使用并打包jar调用

其实线上使用可以多种方式,比如pom引入spring boot自己去写一个接口实现; 但如果并发不是很高,可以使用synchronized关键字进行,若对并发有要求,建议直接使用 unidbg-boot-server开源项目; 从github下拉,https://github.com/anjia0532/unidbg-boot-server 常见问题:…

Neo-reGeorg测试

1、前言 趁着春节刚开工不太忙,把以前的坑填一下。 主要是针对反向代理、隧道工具进行学习和测试。 之前测试过FRP,HTTPTunnel,NPS,都比较简单,而且上面工具也可以用在普通需求下使用。 reGeorg和Neo-reGeorg非常适合…

常用RTOS详细说明

鸿蒙OS HarmonyOS是一款面向全场景的开源分布式操作系统,是华为自主研发的操作系统。 鸿蒙OS实现模块化耦合,可应用在不同的设备上。 鸿蒙OS架构分为三层: 第一层是内核第二层是基础服务第三层是程序框架 。 鸿蒙OS底层三部分组成&#x…

《U型理论》速读

文章目录书籍信息概览踏上发现的旅程大火带来的启示踏上 U 型之旅学习和变革的4个层次组织的盲点社会的盲点科学的哲学基础关于界点下载观察感知自然流现结晶塑造原型运行社会场域理论的 21 个命题个人行动谈话行动自然流现的原则和实践:引领深刻的创新和变革视觉记…

Windows Server 2016搭建DNS服务

1:搭建DNS服务的目的是为了解析vCenter,当初安装时候没有用DNS解析,主机名是localhost无法安装vTPM虚拟Windows 11。 2:准备一台Windows Server 2016的主机,设置好固定IP地址,DNS就是本机的IP地址。 3:在服务器管理中…

Maven知识点-关于dependencyManagement和pluginManagement

前言 dependencyManagement和pluginManagement如何使用以及什么意思?我想懂点Maven的应该都明白,无非是依赖和插件的管理(版本),一般多用于Maven项目的继承和聚合模式中。 这里不是讲解dependencyManagement和plugin…

PCB丝印的字符有哪些作用?

PCB字符也就是行业内常说的“丝印”PCB丝印在一般的PCB板子都可以看到,那么PCB丝印有那些作用呢。 1、大家都知道各种各样的电子元器件数不胜数,那么如何区分PCB这个焊盘是贴什么电子元器件的呢?实际上就是通过PCB板子上的丝印字符去判断每一…

package.json配置详解

npm 介绍 npm 是随同 Node.js 一起安装的包管理工具,能解决 Node.js 代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从 NPM 服务器下载别人编写的第三方包到本地使用;许用户从 NPM 服务器下载并安装别人编写的命令行程序到本地使用;允许用户将自己编写的包或命令行…

【云原生 | Docker 高级篇】11、Docker 私有镜像仓库 Harbor 安装及使用教程

目录 一、Harbor 介绍 二、Harbor 的优势 三、Harbor 部署安装 3.1 部署环境 3.2 为 Harbor 自签发证书 3.3 安装 Harbor 3.4 设置开机自启 四、Harbor 图像化界面使用说明 4.1 修改本地 hosts 文件 4.2 访问 harbor 4.3 创建项目 五、测试使用 harbor 私有镜像仓库…

form 表单只有一个input 时,回车自动提交表单造成页面刷新效果

现象&#xff1a;el-form 中仅有一个input&#xff0c;input上设置了回车响应事件&#xff0c;首次按回车键后&#xff0c;页面刷新&#xff0c;再次按回车才执行了响应事件 <el-form ref"form" submit.native.prevent><el-form-item><el-input keyu…

C#学习记录——【实例】C#实现OPC Client

最近学习测试用C#开发OPC客户端连接OPC服务器&#xff0c;防止遗忘&#xff0c;记录学习测试结果。 1、OPC基础知识 1.1、OPC概述 OPC是Object Linking and Embedding&#xff08;OLE&#xff09;for Process Control 的缩写&#xff0c;它是微软公司的对象链接和嵌入技术在…

【JavaEE】认识HTTP协议

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【JavaEE】 ✈️✈️本篇内容:认识HTTP协议、请求。 &#x1f680;&#x1f680;代码存放仓库github&#xff1a;JavaEE仓库&#xff01; ⛵⛵作者简介&#xff1…