温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

uniapp怎么实现微信小程序的电子签名效果

发布时间:2022-05-12 10:51:46 来源:亿速云 阅读:616 作者:iii 栏目:开发技术

今天小编给大家分享一下uniapp怎么实现微信小程序的电子签名效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    开发框架:uniapp
    开发语言:vue2
    展示平台:微信小程序(实际可以兼容多个平台)

    标签和样式没什么好说的,这里绘制了简单的页面,见下图:

    uniapp怎么实现微信小程序的电子签名效果

    1、标签和样式

    <template>
    	<view class="page-content">
    		<view class="form">
    			<view class="form-content">
    				<canvas class="form-content__canvas" canvas-id="canvas_sign" @touchstart="touchstart"
    					@touchmove="touchmove" @touchend="touchend" disable-scroll="true"></canvas>
    			</view>
    
    			<view class="form-footer">
    				<button class="form-footer__reset" @click="autographClick(1)">重置</button>
    				<button class="form-footer__save" @click="autographClick(2)">保存</button>
    				<button class="form-footer__preview" @click="autographClick(3)">预览</button>
    			</view>
    		</view>
    
    	</view>
    </template>
    
    
    <style lang="scss" scoped>
    	/*
    	* 横屏后的适配方案
    	* @param $rpx为需要转换的字号
    	* @参考 https://blog.csdn.net/sdfsfsdscd/article/details/91375066
    	**/
    	@function tovmin($rpx) {
    		@return #{$rpx * 100 / 750}vmin;
    	}
    
    	.page-content {
    		width: 100vw;
    		height: 100vh;
    
    		.form {
    			display: flex;
    			flex-direction: column;
    			width: 100%;
    			height: 100%;
    
    			.form-content {
    				width: 100%;
    				height: 100%;
    
    				&__canvas {
    					height: calc(100vh - tovmin(20) - tovmin(120) - constant(safe-area-inset-bottom));
    					height: calc(100vh - tovmin(20) - tovmin(120) - env(safe-area-inset-bottom));
    					width: 100vw;
    				}
    			}
    
    			.form-footer {
    				padding-top: tovmin(20);
    				height: calc(tovmin(120) + constant(safe-area-inset-bottom));
    				height: calc(tovmin(120) + env(safe-area-inset-bottom));
    				width: 100%;
    
    				display: flex;
    				flex-direction: row;
    
    				background: #FFFFFF;
    				box-shadow: 0 tovmin(4) tovmin(20) tovmin(2) rgba(183, 183, 183, 0.20);
    
    
    				button {
    					width: 20vw;
    
    					height: tovmin(88);
    					line-height: tovmin(88);
    					border-radius: tovmin(48);
    					text-align: center;
    					font-size: tovmin(36);
    					font-weight: bold;
    				}
    
    				button::after {
    					border: none;
    				}
    
    				&__reset {
    					color: #008AFE;
    					border: tovmin(1) solid #008AFE;
    				}
    
    				&__save {
    					background-image: linear-gradient(135deg, #1BC5FF 0%, #008AFE 100%);
    				}
    
    				&__preview {
    					color: #008AFE;
    					border: tovmin(1) solid #008AFE;
    				}
    			}
    		}
    	}
    </style>

    2、横屏切换

    到【pages.json】文件中添加横屏切换配置
    注意:不同的平台横屏切换将有所不一样。这里是针对微信小程序的横屏适配

    {
    	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    		{
    			"path": "pages/index/index",
    			"style": {
    				"navigationBarTitleText": "亲笔签名",//导航栏标题
    				"pageOrientation": "landscape",//切换横屏
    				"enablePullDownRefresh": false,//关闭下拉刷新
    				"disableScroll": true // 整体页面禁止上下滑动
    			}
    		}
    	],
    	"globalStyle": {
    		"navigationBarTextStyle": "black",
    		"navigationBarBackgroundColor": "#FFFFFF",
    		"backgroundColor": "#f5f5f5",
    		"navigationStyle": "default", // default/custom。custom即取消默认的原生导航栏
    		"mp-alipay": {
    			"transparentTitle": "always",
    			"titlePenetrate": "YES"
    		}
    	}
    }

    然后是绘制逻辑处理,注意点在代码中备注:

    3、绘图

    3.1、初始化数据会吧?

    		data() {
    			return {
    				canvasCtx: '', //绘图图像
    				points: [], //路径点集合
    				hasSign: false,
    				isInit: false,
    			}
    		},
    		onLoad(query) {
    			this.canvasCtx = uni.createCanvasContext('canvas_sign', this) //创建绘图对象
    			//设置画笔样式
    			this.canvasCtx.lineWidth = 6
    			// 设置线条的端点样式
    			this.canvasCtx.lineCap = 'round'
    			// 设置线条的交点样式
    			this.canvasCtx.lineJoin = 'round'
    		},

    3.2、触摸开始时获取起点,会吧?

    			touchstart: function(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)
    				//每次触摸开始,开启新的路径
    				this.canvasCtx.beginPath()
    			},

    3.3、触摸移动获取路径点,会吧?

    			touchmove: function(e) {
    				let moveX = e.changedTouches[0].x
    				let moveY = e.changedTouches[0].y
    				let movePoint = {
    					X: moveX,
    					Y: moveY
    				}
    				this.points.push(movePoint) //存点
    				let len = this.points.length
    				if (len >= 2) {
    					this.draw() //绘制路径
    				}
    
    			},

    3.4、触摸结束,将未绘制的点清空防止对后续路径产生干扰,简单吧?

    			touchend: function() {
    				this.points = []
    				this.canvasCtx.draw(true)
    			},

    3.5、绘制笔迹,没得问题吧?

    这里有几个注意点:

    1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
    2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)
    3.将上一次的终点作为下一次绘制的起点(即清除第一个点)

    			draw: function() {
    				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
    			},

    4、扫尾处理

    上面的实现了,说明就可以签下你大名了。这里扫尾工作(按钮点击功能实现)只是景上添花。根据实际情况不一定要做。

    <script>
    	export default {
    		methods: {
    			// 底部按钮点击操作
    			autographClick(type) {
    				let that = this
    				if (type === 1) {
    					//清空画布
    					this.hasSign = false
    					uni.getSystemInfo({
    						success: function(res) {
    							let canvas = uni.createSelectorQuery().select('.form-content__canvas')
    							canvas.boundingClientRect().exec(function(data) {
    								console.log('canvas', data)
    								console.log('canvas wh:' + data[0].width + 'X' + data[0].height)
    								let canvasw = Math.ceil(data[0].width)
    								let canvash = Math.ceil(data[0].height)
    								that.canvasCtx.fillStyle = '#fff'
    								that.canvasCtx.fillRect(0, 0, canvasw, canvash)
    								that.canvasCtx.draw(true)
    							})
    						}
    					})
    
    				} else {
    					if (!this.hasSign) {
    						uni.showToast({
    							title: '签名不能为空',
    							icon: 'none',
    							duration: 2000
    						})
    						return
    					}
    					uni.getSystemInfo({
    						success: function(res) {
    							let canvas = uni.createSelectorQuery().select('.form-content__canvas')
    							canvas.boundingClientRect().exec(function(data) {
    								console.log('canvas saveSign:', data[0].width + 'X' + data[0].height)
    								let canvasw = Math.ceil(data[0].width)
    								let canvash = Math.ceil(data[0].height)
    								uni.canvasToTempFilePath({
    									destWidth: canvasw,
    									destHeight: canvash,
    									fileType: 'jpg',
    									canvasId: 'canvas_sign',
    									success: function(res) {
    										console.log('图片导出成功:', res)
    										let path = res.tempFilePath
    
    										// 保存图片
    										if (type === 2) {
    											that.uploadPic(path)
    										} else if (type === 3) {
    											// 预览图片
    											uni.previewImage({
    												urls: [path]
    											})
    										}
    									},
    									fail: (err) => {
    										// http://tmp/2LVQyvzddk2R820a9009dff43323d8e7fc9ef7a8d076.jpg
    										console.log('图片导出失败:', err)
    									}
    								})
    							})
    						}
    					})
    				}
    			},
    
    			// 图片上传处理
    			uploadPic(tempFile) {
    				// 1、将本地图片上传到服务器(假装是七牛云服务器)
    				// 2、将七牛云返回的链接,上传到我们的服务器平台
    				console.log("------:", tempFile);
    				uni.showLoading({
    					title: '正在上传中...'
    				})
    				setTimeout(() => {
    					uni.showToast({
    						title: '假装签名上传成功',
    						duration: 2000,
    						icon: 'none'
    					});
    				}, 1000);
    			}
    		}
    	}
    </script>

    以上就是“uniapp怎么实现微信小程序的电子签名效果”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI