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

前言

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



效果展示

在这里插入图片描述



代码展示

触摸开始(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
代码地址:https://gitcode.net/Robergean/signature

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值