在开发项目中有签名/签字的需求,以下实现:
<template><view class="new_file" v-if="showAutograph"><view class="popupBox"><view class="popupTopBox">签字板</view><canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas><view class="determineBtn" @click="confirm">确定</view></view><view class="closeIcon" @click="cancel"><van-icon name="close" size="40" /></view></view>
</template><script>
export default {data() {return {showAutograph: false,ctx: '', //绘图图像points: [], //路径点集合signature: '',type: ''};},methods: {//创建并显示签名画布autograph(type) {this.type = typethis.showAutograph = 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.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 = [];},/* ***********************************************# 绘制笔迹# 1.为保证笔迹实时显示,必须在移动的同时绘制笔迹# 2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)# 3.将上一次的终点作为下一次绘制的起点(即清除第一个点)************************************************ */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() {let that = this;uni.getSystemInfo({success: function (res) {let canvasw = res.windowWidth;let canvash = res.windowHeight;that.ctx.clearRect(0, 0, canvasw, canvash);that.ctx.draw(true);}});},//关闭并清空画布cancel() {this.showAutograph = false;this.clear();},//完成绘画并保存到本地confirm() {let that = this;uni.canvasToTempFilePath({canvasId: 'mycanvas',success: function (res) {that.$emit('ok', that.type, res.tempFilePath)that.cancel()}});}}
};
</script><style lang="less" scoped>
page {font-family: Source Han Sans CN;
}
.new_file {position: fixed;left: 0;top: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.5);.buttONbOX {position: fixed;left: 50%;top: 50%;}.popupBox {position: fixed;left: 50%;bottom: 188rpx;transform: translate(-50%, 0);width: 720rpx;height: 1055rpx;background: #ffffff;border-radius: 16rpx;.popupTopBox {width: 100%;height: 80rpx;background: #1f75b4;border-radius: 16rpx 16rpx 0px 0px;text-align: center;line-height: 80rpx;font-size: 32rpx;color: #ffffff;}.mycanvas {width: 100%;height: 860rpx;}.determineBtn {width: 280rpx;height: 69rpx;background: #1f75b4;border-radius: 35rpx;margin: 0 auto;font-size: 30rpx;color: #ffffff;text-align: center;line-height: 69rpx;}}.closeIcon {position: fixed;left: 50%;bottom: 92rpx;transform: translate(-50%, 0);width: 50rpx;height: 50rpx;image {width: 100%;height: 100%;}}
}
</style>
实现效果: