uniapp:手写签名,多张图合成一张图

要实现的内容:手写签名,协议内容。点击提交后:生成1张图片,有协议内容和签署日期和签署人。
实现的效果图如下:
在这里插入图片描述
在这里插入图片描述

1、签名页面

<template>
	<view class="index">
		<u-navbar title="电子协议" :is-back="false" :border-bottom="false" title-color="#333" :background="{background:''}">
		<view class="page_navbar_warp">
				<image src="../../static/icon/0.png" mode="" class="page_navbar_commonImg" @click="$go(1,1)"></image>
			</view>
		</u-navbar>
		<image src="https://www.*****/xieyi.png" mode="" class="banner"></image>
			<view class="signBox">
				<view class="title">签名区</view>
				<view style="width: 700rpx;height: 450rpx;">
					<l-signature disableScroll backgroundColor="rgba(255, 249, 238, .0)" ref="signatureRef" penColor="#333" :penSize="5" :openSmooth="true" ></l-signature>
				</view>
			</view>
		<view class="footer">
			<view class="btn1 t-c" @click="onClick('undo')">撤消</view>
			<u-button class="btn2 t-c" @click="onClick('save')" :loading="loading">提交</u-button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				loading:false,
			}
		},
		methods:{
			onClick(type) {
				 if(type == 'openSmooth') {
					 this.openSmooth = !this.openSmooth
					 return
				 }
				if (type == 'save') {
					this.$refs.signatureRef.canvasToTempFilePath({
						success: (res) => {
							// 是否为空画板 无签名
							// 生成图片的临时路径
							// H5 生成的是base64
							let url = res.tempFilePath;
							console.log(res);
							if(res.isEmpty){
								this.$toast('请签名')
							}else{
								this.loading = true;
								this.$uploadImage('common/upload', url).then(res => {
									this.loading = false;
									if(res.code == 1){
										this.$go(2,'/pages/mine/canvas?signImg='+res.data.fullurl)
									}
								})
							}
						}
					})
					return
				}
				if (this.$refs.signatureRef) this.$refs.signatureRef[type]()
			}
		}
	}
</script>

<style scoped lang="scss">
	.index{
		min-height: 100vh;
		position: relative;
		.banner{
			display: block;
			width: 585rpx;
			height: 416rpx;
			margin: auto;
		}
		.signBox{
			border: 1rpx dashed #BF9350;
			width: 700rpx;
			height: 500rpx;
			margin: 32rpx auto;
			.title{
				padding-top: 32rpx;
				font-size: 40rpx;
				color: #BF9350;
				padding-left: 32rpx;
			}
		}
		.footer{
			position: fixed;
			left: 0;
			bottom: 0;
			width: 750rpx;
			height: 98rpx;
			background: #fff;
			box-shadow: 0rpx 3rpx 6rpx 1rpx rgba(0,0,0,0.32);
			padding: 0 50rpx;
			display: flex;
			align-items: center;
			justify-content: space-between;
			.btn1{
				width: 300rpx;
				height: 81rpx;
				border-radius: 41rpx 41rpx 41rpx 41rpx;
				border: 1rpx solid #BF9350;
				font-size: 32rpx;
				color: #BF9350;
			}
			.btn2{
				width: 300rpx;
				height: 81rpx;
				background: #BF9350;
				border-radius: 41rpx 41rpx 41rpx 41rpx;
				font-size: 32rpx;
				color: #fff;
			}
		}
	}
</style>

2、canvas页面,用来合成1张图

<template>
	<view class="demo">
		<u-navbar title="电子协议" :is-back="false" :border-bottom="false" title-color="#333" :background="{background:'#FFFAF3'}">
		<view class="page_navbar_warp">
				<image src="../../static/icon/0.png" mode="" class="page_navbar_commonImg" @click="$go(1,1)"></image>
			</view>
		</u-navbar>
		<canvas :style="{ width: canvasW + 'px', height: canvasH + 'px' }" canvas-id="myCanvas" id="myCanvas"></canvas>
		<view class="footer">
			<view class="btn1 t-c" @click="$go(1,1)">取消</view>
			<u-button class="btn2 t-c" @click="submit" :loading="loading" shape="circle" :ripple="true">提交</u-button>
		</view>
	</view>
</template>
<script>
	export default {
		components: {},
		data() {
			return {
				loading:false,
				canvasW:0, // 画布宽
				canvasH:0, // 画布高
				SystemInfo:{}, // 设备信息
				goodsImg: {}, // 协议图片
				signImg:{}, // 签名图片
				signW:120, // 签名图片大小
				bgImg:{},
				year:'',
				mon:'',
				date:'',
				tempFilePath:'',
			}
		},
		async onLoad(option) {
			var start = new Date();
			this.year = start.getFullYear();
			this.mon = start.getMonth() + 1;
			this.date = start.getDate();
			 // 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100%
			this.SystemInfo = await this.getSystemInfo();
			// 获取协议图片,签名二维码图片信息,APP端会返回图片的本地路径(H5端只能返回原路径)
			this.bgImg = await this.getImageInfo('https://www.*******/xieyi.png');
			this.goodsImg = await this.getImageInfo('https://www.*******/bg.png');
			this.signImg = await this.getImageInfo(option.signImg);
			this.canvasW = this.SystemInfo.windowWidth; // 画布宽度
			// #ifdef APP-PLUS
			this.canvasH = this.SystemInfo.windowHeight-94-uni.getSystemInfoSync().statusBarHeight;  // 画布高度 = 页面高度-(导航栏固定44px+footer的50px+APP内手机双跳栏的高度)
			// #endif
			// #ifdef H5
			this.canvasH = this.SystemInfo.windowHeight-94; 
			// #endif
			// 如果主图,二维码图片,设备信息都获取成功,开始绘制海报,这里需要用setTimeout延时绘制,否则可能会出现图片不显示。
			if(this.goodsImg.errMsg == 'getImageInfo:ok' && this.signImg.errMsg == 'getImageInfo:ok' && this.SystemInfo.errMsg == 'getSystemInfo:ok'){
				uni.showToast({
					icon:'loading',
					mask:true,
					duration:10000,
					title: '加载中,请稍后',
				});
				setTimeout(()=>{
					var ctx = uni.createCanvasContext('myCanvas', this);
					// 填充背景
					ctx.drawImage(this.bgImg.path, 0, 0, this.canvasW, this.canvasH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
					
					// 绘制协议主图
					ctx.drawImage(this.goodsImg.path, 50, 60, this.canvasW-100, this.canvasW-180) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)

					// 签署日期
					ctx.setFontSize(16)
					ctx.setFillStyle('#333')
					ctx.fillText(`签署日期:${this.year}${this.mon}${this.date}`, 50, this.canvasH -this.signW-80);
					
					// 签署人
					ctx.setFontSize(14)
					ctx.setFillStyle('#333')
					ctx.fillText('签署人:', 50, this.canvasH -this.signW-40);
					// 签署人
					ctx.drawImage(this.signImg.path, 90, this.canvasH-this.signW-80, this.signW, this.signW) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度,二维码的宽,高)
					
					ctx.draw(true,(ret)=>{ // draw方法 把以上内容画到 canvas 中。
						console.log(ret) 
						uni.showToast({
							icon:'success',
							mask:true,
							title: '绘制完成',
						});
						uni.canvasToTempFilePath({ // 保存canvas为图片
							canvasId: 'myCanvas',
							quality: 1,
							complete: (res)=> {
								console.log(res)
								// 在H5平台下,tempFilePath 为 base64, // 图片提示跨域 H5保存base64失败,APP端正常输出临时路径
								if(res.tempFilePath){
									this.tempFilePath = res.tempFilePath;
								}
							},
						})
					});
				},1500)
			}else{
				console.log('err')
			}
		},
		methods: {
			submit(){
				this.loading = true;
				console.log('需要提交给后台的图片'this.tempFilePath)
			},
			// 获取图片信息
			getImageInfo(image) {
				return new Promise((req, rej) => {
					uni.getImageInfo({
						src: image,
						success: function(res) {
							req(res)
						},
					});
				})
			},
			
			// 获取设备信息
			getSystemInfo(){
				return new Promise((req, rej) => {
					uni.getSystemInfo({
					    success: function (res) {
					        req(res)
					    }
					});
				})
			},
		},
	}
</script>

<style scoped lang="scss">
	.footer{
		position: fixed;
		left: 0;
		bottom: 0;
		width: 750rpx;
		height: 50px;
		box-shadow: 0rpx 3rpx 6rpx 1rpx rgba(0,0,0,0.32);
		padding: 0 50rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		background: #fff;
		.btn1{
			width: 300rpx;
			height: 40px;
			border-radius: 41rpx 41rpx 41rpx 41rpx;
			border: 1rpx solid #BF9350;
			font-size: 32rpx;
			color: #BF9350;
		}
		.btn2{
			width: 300rpx;
			height: 40px;
			background: #BF9350;
			border-radius: 41rpx 41rpx 41rpx 41rpx;
			font-size: 32rpx;
			color: #fff;
		}
	}
</style>

备注:
1、协议页面内用的l-signature来自于uniapp插件市场
2、canvas页面灵感来自于之前写过的一篇绘制海报文章
3、页面中用到的 xieyi.png(协议内容)、bg.png(底图)、以及签名后的option.signImg(签名图),都需要后台设置允许跨域。否则H5就会报错画布污染无法生成base64。
在这里插入图片描述
这个问题在APP内不存在,只有H5会出现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《MySQL》第十二篇 数据类型

目录 一. 整数类型二. 浮点类型三. 日期和时间类型四. 字符串类型五. 枚举值类型六. 二进制类型七. 小结 MySQL 支持多种数据类型&#xff0c;学习好数据类型&#xff0c;才能更好的学习 MySQL 表的设计&#xff0c;让表的设计更加合理。 一. 整数类型 类型大小SIGNED(有符号)…

7D透明屏的市场应用广泛,在智能家居中有哪些应用表现?

7D透明屏是一种新型的显示技术&#xff0c;它能够实现透明度高达70%以上的显示效果。这种屏幕可以应用于各种领域&#xff0c;如商业广告、展览展示、智能家居等&#xff0c;具有广阔的市场前景。 7D透明屏的工作原理是利用光学投影技术&#xff0c;将图像通过透明屏幕投射出来…

国产化 | 走近人大金仓-KingbaseES数据库

引入 事务隔离级别 || KingbaseES数据库 开篇 1、KingbaseES数据库 百度百科&#xff1a;金仓数据库的最新版本为KingbaseES V8&#xff0c; KingbaseES V8在系统的可靠性、可用性、性能和兼容性等方面进行了重大改进&#xff0c;支持多种操作系统和硬件平台支持Unix、Linux…

基于罪名法务智能知识图谱(含码源):基于280万罪名预测、20W法务问答与法律资讯问答功能

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

ThinkPHP8知识详解:给PHP8和MySQL8添加到环境变量

在PHPenv安装的时候&#xff0c;环境变量默认的PHP版本是7.4的&#xff0c;MySQL的版本是5.7的&#xff0c;要想使用ThinkPHP8来开发&#xff0c;就必须修改环境变量&#xff0c;本文就详细讲解了如果修改PHP和MySQL的环境变量。 1、添加网站 启动phpenv&#xff0c;网站&…

019 - STM32学习笔记 - Fatfs文件系统(一) - FatFs文件系统初识

019 - STM32学习笔记 - Fatfs文件系统&#xff08;一&#xff09; - FatFs文件系统初识 最近工作比较忙&#xff0c;没时间摸鱼学习&#xff0c;抽空学点就整理一点笔记。 1、文件系统 在之前学习Flash的时候&#xff0c;可以调用SPI_FLASH_BufferWrite函数&#xff0c;将数…

四步从菜鸟到高手,Python编程真的很简单(送书第一期:文末送书2本)

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支持&#xff0c;我…

临床医学怎样翻译比较 好

近年来&#xff0c;随着不同国家之间医药行业形成的共同研究趋势&#xff0c;临床翻译对于来自不同国家的医疗人员的合作至关重要。那么&#xff0c;临床医学怎样翻译比较 好&#xff0c;北京哪个翻译公司比较专业&#xff1f; 据了解&#xff0c;临床医学翻译包含患者病历记录…

Linux之 Vim 搜索方式

方式一&#xff1a;快速搜索&#xff08;字符串完全匹配&#xff0c;区分大小写&#xff09; 格式&#xff1a; / 关键词 or &#xff1f; 关键词 /内容 #按回车键搜索 从上到下查找 ?内容 #按回车键搜索 从下到上查找 优点&#xff1a;快速定位到该关键字 回车之后&…

【Lua学习笔记】Lua进阶——Require,三目运算

文章目录 Require短路判断实现三目运算符 Require 这是文件aaa.lua的内容 aaa.lua: a 10 local b 20 print("我是aaa")这是文件example.lua的内容 example.lua: a 100 print(a) require("aaa") --require调用其他脚本文件 print(a) print(b) print(&…

Psim 2022仿真软件的安装--Psim电力仿真实战教程

文章目录 Psim 2022 仿真软件安装及使用教程软件介绍1.下载psim 2022安装软件&#xff0c;有需要的亲请联系作者。2.点击安装文件3.点击进行安装&#xff1a;4.安装完成&#xff0c;打开软件&#xff0c;开始仿真5.仿真模型介绍5.1.单相全控整流电路仿真5.2 三相PFC可控整流电路…

【点选验证码】生成点选验证码图片

生成点选验证码图片 参考博客&#xff1a;https://blog.csdn.net/sinat_39629323/article/details/121989609 from tqdm import tqdm from PIL import Image, ImageDraw, ImageFont, ImageOps import shutil,os import numpy as np import cv2 import math import random fil…

Mysql的增删改查

一.增加数据&#xff08;insert&#xff09; insert into 表名&#xff08;列名1&#xff0c;列名2&#xff0c;列名3&#xff0c;.....列名n&#xff09;values(值&#xff0c;值&#xff0c;值&#xff0c;....值&#xff09; insert into userinfo(id,name,age) values(&quo…

CSS3 实现边框圆角渐变色渐变文字效果

.boder-txt {width: 80px;height: 30px; line-height: 30px;padding: 5px;text-align: center;border-radius: 10px;border: 6rpx solid transparent;background-clip: padding-box, border-box;background-origin: padding-box, border-box;/*第一个linear-gradient表示内填充…

二级制部署kubernetes(1.20)

&#x1f618;作者简介&#xff1a;一名运维工作人员。 &#x1f44a;宣言&#xff1a;人生就是B&#xff08;birth&#xff09;和D&#xff08;death&#xff09;之间的C&#xff08;choise&#xff09;&#xff0c;做好每一个选择。 &#x1f64f;创作不易&#xff0c;动动小…

RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”

RISC-V公测平台Web Server地址&#xff1a;http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施&#xff0c;无论是用户访问网站&#xff0c;还是后端服务提供商和开发者构建各种应用程序&#xff0c;Web Server都在其中扮演着至关重要的角色。 显而易见…

服务器 Docker Alist挂载到本地磁盘(Mac版)夸克网盘

1.服务器下载alist 默认有docker环境 docker pull xhofe/alist2.生成容器 -v /home/alist:/opt/alist/data 这段意思是alist中的数据映射到docker 主机的文件夹&#xff0c;/home/alist就是我主机的文件夹&#xff0c;这个文件夹必须先创建 docker run -d --restartalways…

Node.js 安装与版本管理(nvm 的使用)

安装 Node.js Node.js 诞生于 2009 年 5 月&#xff0c;截至今天&#xff08;2022 年 3 月 26 号&#xff09;的最新版本为 16.14.2 LTS 和 17.8.0 Current&#xff0c;可以去官网下载合适的版本。 其中&#xff0c;LTS&#xff08;Long Term Support&#xff09; 是长期维护…

【Matter】基于Ubuntu 22.04 编译chip-tool工具

前言 编译过程有点曲折&#xff0c;做下记录&#xff0c;过程中&#xff0c;有参考别人写的博客&#xff0c;也看github 官方介绍&#xff0c;终于跑通了~ 环境说明&#xff1a; 首先需要稳定的梯子&#xff0c;可以访问“外网”ubuntu 环境&#xff0c;最终成功实验在Ubunt…

Unity XML3——XML序列化

一、XML 序列化 ​ 序列化&#xff1a;把对象转化为可传输的字节序列过程称为序列化&#xff0c;就是把想要存储的内容转换为字节序列用于存储或传递 ​ 反序列化&#xff1a;把字节序列还原为对象的过程称为反序列化&#xff0c;就是把存储或收到的字节序列信息解析读取出来…