uniapp使用vue3开发微信小程序,实现电子签名

733 阅读1分钟

话不多说,直接上完整代码:

<template>
	<view>
				<canvas  class="autograph-canvas" type="2d" disable-scroll id="myCanvas" canvas-id="myCanvas" 
					:style="{width:props.width, height:props.height, display: 'block'}" @touchstart="handleTouchStart"
					@touchmove="handleTouchMove" @touchend="handleTouchEnd" @touchcancel="handleTouchEnd"
					@error="handleTouchEnd"></canvas>

	</view>
</template>

<script setup>
	import {
		ref,
		onMounted,
		reactive
	} from 'vue'
	import { getCurrentInstance } from 'vue';
	
	let myCanvas = null
	const instance = getCurrentInstance(); 
	const props = defineProps({
		width: {
			type: String,
			default: '500rpx'
		},
		height: {
			type: String,
			default: '600rpx'
		},
		lineWidth: {
			type: Number,
			default: 2
		},
		lineColor: {
			type: String,
			default: '#000000'
		}
	})
	const state = reactive({
		isDraw: false, // 是否能画画
		canvasElement: null,
		canvasContext: null,
		oldPosition: {
			x: 0,
			y: 0
		}
	})
	// 初始化canvas
	const initCanvas = (fn) => {
		const query =  uni.createSelectorQuery().in(instance)
		query.select('#myCanvas').fields({
			node: true,
			size: true,
			context: true,
		}).exec(res => {
			const canvas =  res[0].node
			const context =  canvas.getContext('2d')
			const dpr = uni.getSystemInfoSync().pixelRatio
			canvas.width = res[0].width * dpr
			canvas.height = res[0].height * dpr
			context.scale(dpr, dpr)
			myCanvas = canvas
			state.canvasContext=context
			console.log(res,dpr,canvas,myCanvas.width);
			fn &&	fn()

		})
	}
	onMounted(()=>{
		initCanvas()
	})
	// 描绘canvas
	const drawCanvas = (position) => {
		if (state.canvasContext) {
			state.canvasContext.strokeStyle = props.lineColor
			state.canvasContext.lineWidth = props.lineWidth
			state.canvasContext.beginPath()
			state.canvasContext.moveTo(state.oldPosition.x, state.oldPosition.y)
			state.canvasContext.lineTo(position.x, position.y)
			state.canvasContext.stroke()
			state.canvasContext.closePath();
			state.oldPosition = {
				x: position.x,
				y: position.y
			}
		}
	}
	// 在画布触摸开始
	const handleTouchStart = (e) => {
		const x = e.touches[0].x;
		const y = e.touches[0].y;
		state.oldPosition = {
			x: x,
			y: y
		}
		state.isDraw = true
	}
	// 在画布触摸移动
	const handleTouchMove = (e) => {
		if (state.isDraw) {
			let positionItem = e.touches[0]
			if (state.canvasContext) {
				drawCanvas(positionItem, true)
			} else {
				initCanvas(() => {
					drawCanvas(positionItem, true)
				})
			}
		}
	}
	// 在画布触摸结束
	const handleTouchEnd = () => {
		state.isDraw = false
	}
	// 清除画布
	const clearCanvas = () => {
		if (myCanvas) {
			const x = myCanvas.width
			const y = myCanvas.height
			state.canvasContext.clearRect(0, 0, x, y)
		}

	}

	// 获取临时文件
	const getCavasTempFile = () => {
	
		return new Promise((resolve, reject) => {
			wx.canvasToTempFilePath({
				canvas:myCanvas ,
				destWidth:'200',
				destHeight:'200',
				 fileType: "jpg",
				success: (res) => {
					resolve(res)
				},
				fail: (e) => {
					console.log('e',e);
					reject('图片临时文件生成失败')
				}
			},instance)
		})
	}
   const getOnlieUrl = async ()=>{
	  const url =   await getCavasTempFile() 
	  return {path:url.tempFilePath}
   }
	defineExpose({
		clearCanvas,
		getOnlieUrl
	})
</script>

<style lang="scss" scoped>

</style>