Skip to content

组件 ​

javascript
<template>
	<view style="position: relative;">
		<view class="singatureTag">签名区域</view>
		<canvas class='firstCanvas' canvas-id="firstCanvas" @touchmove='move' @touchstart='start($event)' @touchend='end'
								@touchcancel='cancel' @longtap='tap' disable-scroll='true' @error='error'>
							 </canvas> 
							 
		<!-- <view class="j-flex">
			<button @click="clearClick">重置</button>
			<button @click="overSign">确认</button>
		</view> -->
		
		<!-- <image :src="filePath" class="img" mode="aspectFill"></image> -->
		
	</view>
</template>

<script>
	var content = null;
	var touchs = [];
	var canvasw = 0;
	var canvash = 0;
	var _that;
	//获取系统信息
	uni.getSystemInfo({
		success: function(res) {
			console.log(res)
			canvasw = res.windowWidth;
			canvash = res.windowHeight;
		},
	})
	//签名
	export default {
		name:"canvasB",
		data() {
			return {
				filePath:'',
			};
		},
		props:{
			
		},
		created() {
			
		},
		mounted() {
			//获得Canvas的上下文
			content = uni.createCanvasContext('firstCanvas',_that)
			//设置线的颜色
			content.setStrokeStyle("#000")
			//设置线的宽度
			content.setLineWidth(5)
			//设置线两端端点样式更加圆润
			content.setLineCap('round')
			//设置两条线连接处更加圆润
			content.setLineJoin('round')
			
			_that = this
		},
		methods:{
			//签署完成
			overSign: function() {
				if (_that.isEnd) {
					// uni.showLoading({
					// 	title:'签名生成...'
					// })
					content.draw(true,setTimeout(()=>{
						uni.canvasToTempFilePath({
							canvasId: 'firstCanvas',
							x:0,
							y:0,
							width:340,
							height:200,
							success: (res) => {
								uni.hideLoading()
								console.log(res)
								var file_path = res.tempFilePath
								_that.filePath = file_path
								_that.$emit('getFile', file_path)
							},
							complete:()=>{
								uni.hideLoading()
							}
						})
						
						return false
						_that.clearClick()
					},1000))
					
				} else {
					uni.showToast({
						title: '请先完成签名',
						icon: "none",
						duration: 1500,
						mask: true
					})
				}
			},

			// 画布的触摸移动开始手势响应
			start(event){
				// console.log(event)
				// console.log("触摸开始" + event.changedTouches[0].x)
				// console.log("触摸开始" + event.changedTouches[0].y)
				//获取触摸开始的 x,y
				let point = {
					x: event.changedTouches[0].x,
					y: event.changedTouches[0].y
				}
				console.log(point)
				touchs.push(point);
			},
			// 画布的触摸移动手势响应
			move(e){
				let point = {
					x: e.touches[0].x,
					y: e.touches[0].y
				}
				// console.log(point)
				touchs.push(point)
				if (touchs.length >= 2) {
					this.draw(touchs)
				}
			},
			// 画布的触摸移动结束手势响应
			end(e){
				// 设置为已经签名
				this.isEnd = true;
				console.log('end')
				// 清空轨迹数组
				touchs.pop()
			},
			isSignEnd(){
				return this.isEnd
			},
			// 画布的触摸取消响应
			cancel: function(e) {
			},

			// 画布的长按手势响应
			tap: function(e) {
			},
			//画布触摸错误
			error: function(e) {
			},
			//绘制
			draw: function(touchs) {
				let point1 = touchs[0]
				let point2 = touchs[1]
				touchs.shift()
				content.moveTo(point1.x, point1.y)
				content.lineTo(point2.x, point2.y)
				content.stroke()
				content.draw(true)
			},
			
			//清除操作
			clearClick: function() {
				// 设置为未签名
				this.isEnd = false
				//清除画布
				content.clearRect(0, 0, canvasw, canvash)
				content.draw(true)
			},
		}
	}
</script>

<style scoped>
.firstCanvas{
	width: 100%;
	height: 300rpx;
	margin: 0 auto;
	border: 1rpx solid #ccc;
}
.img{
	width: 100%;
	height: 300rpx;
}

.singatureTag{
  position: absolute;
  top: 0rpx;
  left: 0rpx;
  font-size: 140rpx;
  color: #e6e6e6;
  width: 100%;
  text-align: center;
  letter-spacing: 8rpx;
  line-height: 300rpx;
}
</style>

页面 ​

html
submitA(){
				if(!this.$refs.sign.isSignEnd){
					this.showToast('请先签名!!')
					return
				}
				uni.showLoading({
					title:'提交中...'
				})
				this.$refs.sign.overSign();
			},
			// #ifdef APP
			readFileAsBase64(file, callback) {
			    // 创建FileReader对象
			    var reader = new plus.io.FileReader();
			 
			    reader.onloadend = function(e) {
			        // 当读取操作完成时, 此事件被触发
			        // e.target.result 包含了文件的数据内容
					console.log(e)
			        var base64 = e.target.result;
			        callback(base64);
			    };
			 
			    // 以DataURL的形式读取文件内容
			    reader.readAsDataURL(file);
			},
			// #endif
			submitB(filepath){
				// #ifdef APP
				var filepath = plus.io.convertLocalFileSystemURL(filepath) //绝对路径
				this.readFileAsBase64(filepath,res=>{
					console.log(res)
					this.$api.pickBackSubmit({
						code:this.detail.codeNum,
						sign:res
					}).then(res=>{
						console.log(res)
					}).finally(res=>{
						this.$refs.sign.clearClick();
					})
				})
				return false
				// #endif
				console.log(filepath)
				this.$api.pickBackSubmit({
					code:this.detail.codeNum,
					sign:filepath
				}).then(res=>{
					console.log(res)
				}).finally(res=>{
					this.$refs.sign.clearClick();
				})
			}
		}

服务端保存签名图片 ​

php
if(!file_exists($save_path)){
	mkdir($save_path,0777,true);
}
//新文件名
$new_file_name= 'sign_'.$id.'.png';
$sign = str_replace('data:image/png;base64,','',$sign);
//图片信息
file_put_contents($save_path.$new_file_name,base64_decode($sign));

woodlc