h5使用canvas手写签名、图片保存,Base64格式转成图片上传服务器

51 篇文章 1 订阅
<template>
	<div class="page-content">
		<div class="footer">
			<el-button slot="right" @click="handelClearEl()" class="no_btn">清除</el-button>
			<el-button slot="right" @click="saveImage()" class="yes_btn">确定</el-button>
		</div>
		<div class="sign-content">
			<div class="div_canvas_container">
				<canvas id="signCanvas"></canvas>
			</div>
		</div>

		<p>请适当放慢签写速度,确保字迹清晰可辨认!</p>
	</div>
</template>
<script>
	import axios from 'axios'	
	import {
		post
	} from '../../utils/http'
	export default {
		//数字签名
		name: 'Sign',
		data() {
			return {
				imgsrc: "",
				user_token: ''
			}
		},
		mounted() {
			let vm = this;
			vm.digitaSignType = vm.$route.query.type;
			this.$nextTick(() => {
				setTimeout(() => {
					vm.initCanvas()
				}, 100)
			})

		},
		methods: {
			initCanvas() {
				let rate = 2;
				let oCanvas = document.getElementById("signCanvas");
				oCanvas.width = oCanvas.offsetWidth * rate;
				oCanvas.height = oCanvas.offsetHeight * rate;
				let cxt = oCanvas.getContext("2d");
				cxt.fillStyle = "#fff";
				cxt.fillRect(0, 0, oCanvas.width, oCanvas.height);
				cxt.lineWidth = 2 * rate;
				cxt.strokeStyle = "#101010";
				let posX = 0; //x坐标
				let posY = 0; //y坐标
				let position = null;
				let parentPosintin = oCanvas.getBoundingClientRect()

				//手指触摸屏幕可记录此时的位置作为起点
				oCanvas.addEventListener("touchstart", function(event) {
					posX = event.changedTouches[0].clientX;
					posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5;
					cxt.beginPath();
					cxt.moveTo(posX * rate, posY * rate);
				});
				//手指屏滑动画线
				oCanvas.addEventListener("touchmove", function(event) {
					optimizedMove(event);
				});
				let requestAnimationFrame = window.requestAnimationFrame;
				let optimizedMove = requestAnimationFrame ? function(e) {
					requestAnimationFrame(function() {
						move(e);
					});
				} : move;

				function move(event) {
					posX = event.changedTouches[0].clientX + 0.5;
					posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5;
					cxt.lineTo(posX * rate, posY * rate);
					cxt.stroke();
				}
			},
			// 清除画板
			handelClearEl() {
				let oCanvas = document.getElementById("signCanvas");
				let cxt = oCanvas.getContext("2d");
				cxt.clearRect(0, 0, oCanvas.width, oCanvas.height);
			},
			//保存为图片
			saveImage() {
				let oCanvas = document.getElementById("signCanvas");
				let imgBase64 = oCanvas.toDataURL();  
				this.imgsrc = imgBase64;   //此时图片为Base64格式
				const form = new FormData()
				form.append('file', this.dataURLtoBlob(this.imgsrc), 'png')
				form.append('参数', '参数')
				let url = '服务器地址'
				axios.post(url, form, {
						responseType: 'json',
						// withCredentials: true,
						headers: {
							// 'X-Requested-With': 'XMLHttpRequest',
							// 'Content-Type': 'multipart/form-data',
						},
					})
					.then((res) => {
						console.log(res.data)
						var imgUrl = res.data.data + 'png'
						console.log(imgUrl)
						this.fn(imgUrl)
					}).catch(err => {
						this.$message.error(err.message)
					})
				

			},
			//服务器返回的图片地址提交到接口
			fn(imgurl) {
				this.user_token = window.localStorage.getItem("user_token")
				post(
						'接口地址', {
							user_token: this.user_token,
							photo_sign: imgurl
						},
						true
					)
					.then(res => {
						if (res.code === 0) {
							this.$message({
								message: res.message,
								type: 'success'
							})
							this.$router.push({
								name: 'Success',
								params: {

								}
							})
						} else {
							this.$message({
								message: res.message,
								type: 'warning'
							})
						}

					})
					.catch(err => {
						this.$message.error(err.message)
					})
			},
			//Base64格式转成图片
			dataURLtoBlob(dataurl) {
				var arr = dataurl.split(',')
				var mime = arr[0].match(/:(.*?);/)[1]
				var bstr = atob(arr[1])
				var n = bstr.length
				var u8arr = new Uint8Array(n)
				while (n--) {
					u8arr[n] = bstr.charCodeAt(n)
				}
				return new Blob([u8arr], {
					type: mime
				})
			},
			handlePreview(file) {
				console.log(file)
			},
			handleRemove(file) {
				this.fileList = []
			},
			onSuccess(response, file, fileList) {
				console.log(response)
				// this.photo_a=response.data
				console.log(this.fileList)
			},
			onError(err, file, fileList) {
				this.$message.error(err.msg)
			},
		}
	}
</script>
<style lang="less" scoped>
	.div_canvas_container {
		// margin-top: 1.35rem;
		width: 100vw;
		height: 100vh;
		overflow: hidden;
	}

	#signCanvas {
		width: 100%;
		height: 100%;
		background: #FFFFFF;
		border: none;
		box-sizing: border-box;
		overflow: hidden;
	}

	.footer {
		position: fixed;
		z-index: 100;
		right: 0.2rem;
		top: 0.05rem;
	}

	.yes_btn {
		background-color: #FFC300;
		color: #FFFFFF;
	}

	.no_btn {
		border: 1px solid rgba(102, 102, 102, 1);
	}

	p {
		text-align: center;
		position: fixed;
		z-index: 100;
		left: 0;
		bottom: 0.1rem;
		width: 100%;
		font-size: 0.28rem;
		font-weight: 500;
		color: rgba(153, 153, 153, 1);
		line-height: 0.36rem;
	}
</style>

参考:https://blog.csdn.net/qq_39045645/article/details/95354805

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值