uniapp横屏签字板,判断内容非空,签字图片格式转base64

vue2版本,可以直接作为组件引用,,

如果可以请点个赞支持一下!!!!!!!!!!!!!!!

内容效果展示

代码如下

图片旋转是使用两个canvas,第一个画布保存原先的签字图片,再将第二个画布旋转,把图片绘制给带二个画布,

判断内容非空,是保存触摸时记录的轨迹,轨迹数组是空就没有内容

<template>
	<view class="main-content" @touchmove.stop.prevent="">
		<!-- 签字canvas -->
		<canvas 
			class="mycanvas" 
			id="mycanvas" 
			canvas-id="mycanvas" 
			@touchstart="touchstart" 
			@touchmove="touchmove" 
			@touchend="touchend"
		></canvas>
		<!-- 旋转canvas -->
		<canvas
			class="mycanvas"
			:style="{ 'z-index': -1, width: `${screenWidth}px`, height: `${(screenWidth * screenWidth) / screenHeight}px` }"
			id="rotatCanvas"
			canvas-id="rotatCanvas"
		></canvas>
		<!-- 背景 -->
		<view style="width:100vw;height:100vh;background-color: #ffffff; padding-top:700rpx; margin: 0;">
		    <view style="color:#000;font-size: 200rpx; transform: rotate(90deg);">
				签字区
			</view>
		</view>
		<!-- 签字确认 -->
		<view class="button-line">
            <view class="clear-button" @tap="close">返回</view>
			<view v-show="showToast" style="color:red; height:120rpx; line-height: 120rpx; margin-left:200rpx; font-size:30rpx;">
				*请签字后再确认提交
			</view>
			<view style="display: flex;">
				<view class="clear-button" @tap="clear">清除</view>
				<view class="cancel-button" @tap="ifTrue">确定签名</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			ctx: '', //绘图图像
			points: [], //路径点集合
			screenWidth: '',
			screenHeight: '',
			tempPoint: [], //用来存放当前画纸上的轨迹点
			showToast:false,
		}
	},
	mounted() {
		this.createCanvas();
		uni.getSystemInfo({
			success: e => {
				this.screenWidth = e.screenWidth;
				this.screenHeight = e.screenHeight;
			}
		});
	},
	methods: {
        close() {
        	this.$emit('close')
        },
		//创建并显示画布
		createCanvas() {
			this.showCanvas = true;
			this.ctx = uni.createCanvasContext('mycanvas', this); //创建绘图对象
			//设置画笔样式
			this.ctx.lineWidth = 4;
			this.ctx.lineCap = 'round';
			this.ctx.lineJoin = 'round';
		},
		//触摸开始,获取到起点
		touchstart(e) {
			let startX = e.changedTouches[0].x;
			let startY = e.changedTouches[0].y;
			let startPoint = {
				X: startX,
				Y: startY
			};
			this.points.push(startPoint);
			this.tempPoint = []
			this.tempPoint.push(startPoint); //每次开始触摸时记录一次,用作判断是否有签名
			this.ctx.beginPath();
		},
		//触摸移动,获取到路径点
		touchmove(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(); //绘制路径
			}
		},
		// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
		touchend() {
			this.points = [];
		},
		draw() {
			let point1 = this.points[0];
			let point2 = this.points[1];
			this.points.shift();
			this.ctx.moveTo(point1.X, point1.Y);
			this.ctx.lineTo(point2.X, point2.Y);
			this.ctx.stroke();
			this.ctx.draw(true);
		},
		//清空画布
		clear() {
			this.ctx.clearRect(0, 0, this.screenWidth, this.screenHeight);
			this.ctx.draw(true);
			this.tempPoint = [];
		},
		ifTrue(){
			// 判断是否签名 未签名return不发送请求
			if(this.tempPoint.length===0) {
				this.showToast = true
				return
			}
			this.finish()
		},
		//完成绘画并保存到本地
		finish() {
			uni.showLoading({
				title: '加载中',
				mask: true
			});
			this.tempPoint = []
			uni.canvasToTempFilePath(
				{
					canvasId: 'mycanvas',
					success: res => {
						this.rotat(res.tempFilePath);
					},
					fail: (err) => {
						this.$emit('fail', err)
					}
				},
				this
			);
		},
		// 将图片选装
		rotat(e) {
			let rotatCtx = uni.createCanvasContext('rotatCanvas', this); //创建绘图对象
			// 重新定位中心点
			rotatCtx.translate(0, (this.screenWidth * this.screenWidth) / this.screenHeight);
			// 将画布逆时针旋转90度
			rotatCtx.rotate((270 * Math.PI) / 180);
			// 将签字图片绘制进入Canvas
			rotatCtx.drawImage(e, 0, 0, (this.screenWidth * this.screenWidth) / this.screenHeight, this.screenWidth);
			// 保存后旋转后的结果
			rotatCtx.draw(true);
			
			setTimeout(() => {
				// 生成图片并回调
				uni.canvasToTempFilePath(
					{
						canvasId: 'rotatCanvas',
						destWidth:600,
						destHeight:260,
						success: val => {
							const savedFilePath = val.tempFilePath //相对路径
							const path = plus.io.convertLocalFileSystemURL(savedFilePath) //绝对路径
							const fileReader = new plus.io.FileReader()
							fileReader.readAsDataURL(path)
							fileReader.onloadend = (res) => { //读取文件成功完成的回调函数
                                 //输出base64内容
								 this.$emit('sumbit', res.target.result);
							}
							uni.hideLoading()
							
							setTimeout(() => {
								this.close();
							}, 500);
							uni.hideLoading()
						},
						fail: (err) => {
							uni.hideLoading()
							this.$emit('fail', err)
						},
					},
					this
				);
			}, 500);
		},
	
	}
};
</script>

<style lang="scss" scoped>
.main-content {
	width: 100vw;
	height: 100vh;
	// background-color: red;
	position: fixed;
	top: 0rpx;
	left: 0rpx;
	z-index: 9999;
	background-color: #efefef;
}
.mycanvas {
	opacity: 0.8;
	width: 100vw;
	height: 100vh;
	background-color: #efefef;
	position: fixed;
	left: 0rpx;
	top: 0rpx;
	z-index: 2;
}
.button-line {
	transform: rotate(90deg);
	position: fixed;
	bottom: 750rpx;
	left: -750rpx;
	width: 1620rpx;
	height: 120rpx;
	display: flex;
	align-items: center;
	padding:0rpx 50rpx;
	justify-content: space-between;
	z-index: 999;
	background-color: #ffffff;
}

.button-style {
	color: #ffffff;
	width: 180rpx;
	height: 80rpx;
	text-align: center;
	line-height: 80rpx;
	border: 2rpx solid #077cf2;
	border-radius: 10rpx;
}

.clear-button {
	@extend .button-style;
	color: #077cf2;
	background-color: #ffffff;
	margin-right: 20rpx;
}
.cancel-button {
	@extend .button-style;
	color: #ffffff;
	background-color: #077cf2;
}
</style>

参考:uniapp实现横屏签字版_uniapp签字组件-CSDN博客

如果可以请点个赞支持一下!!!!!!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值