uniapp 手写签名并回显
描述
微信小程序B页面手写签名,点击确认后返回到A页面回显签名,复制到程序阅读效果更佳
代码
A页面
<template>
<view>
<view>首页</view>
<navigator url="/pages/sign/sign">跳转到签名</navigator>
<view class="sign-box">
<canvas class="mycanvas" canvas-id="mycanvas"></canvas>
</view>
</view>
</template>
<script>
import { getCanvasWH } from "@/utils/index.js";
export default {
data() {
return {
ctx: "",
};
},
methods: {
// 电子签名回显
async getTempFilePath(tempFilePath) {
const { width, height } = await getCanvasWH(".mycanvas", this);
this.ctx.drawImage(tempFilePath, 0, 0, width, height);
this.ctx.draw();
}
},
onLoad() {
// 一定要初始化
this.ctx = uni.createCanvasContext("mycanvas", this);
},
};
</script>
<style lang="scss">
.sign-box {
width: 100vw;
height: 30vh;
.mycanvas {
width: 100%;
height: 100%;
background-color: #ececec;
}
}
</style>
B页面
<template>
<view class="container sign-view">
<view class="sigh-btns">
<button class="btn" @tap="handleCancel">取消</button>
<button class="btn" @tap="handleReset">重写</button>
<button class="btn" @tap="handleConfirm">确认</button>
</view>
<view class="sign-box">
<canvas
class="mycanvas"
canvas-id="mycanvas"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
></canvas>
<!-- 处理图片的canvas -->
<canvas
canvas-id="camCacnvs"
:style="{ width: height + 'px', height: width + 'px' }"
class="canvsborder"
></canvas>
</view>
</view>
</template>
<script>
// 画布上的点
let tempPoint = [];
export default {
data() {
return {
ctx: "", //绘图图像
points: [], //路径点集合,
width: "",
height: "",
};
},
async onLoad() {
this.ctx = uni.createCanvasContext("mycanvas", this);
// 设置线条宽度
this.ctx.lineWidth = 4;
// 线条形状
this.ctx.lineCap = "round";
// 线条颜色
this.ctx.strokeStyle = "red";
// 线条的交点样式
this.ctx.lineJoin = "round";
const { width, height } = await this.getCanvasWH();
this.width = width;
this.height = height;
},
methods: {
//点击画布
touchstart(e) {
// 点击起点
let startPoint = {
X: e.changedTouches[0].x,
Y: e.changedTouches[0].y,
};
// 储存
this.points.push(startPoint);
// 创建一个路径
this.ctx.beginPath();
},
// 触摸移动
touchmove(e) {
let movePoint = {
X: e.changedTouches[0].x,
Y: e.changedTouches[0].y,
};
this.points.push(movePoint);
if (this.points.length >= 2) {
this.draw();
}
tempPoint.push(movePoint);
},
// 链接线条
draw() {
const pointStart = this.points[0];
const pointEnd = this.points[1];
this.points.shift();
// 链接
this.ctx.moveTo(pointStart.X, pointStart.Y);
this.ctx.lineTo(pointEnd.X, pointEnd.Y);
// 画线条
this.ctx.stroke();
// 画
this.ctx.draw(true);
},
// 触摸停止
touchend() {
this.points = [];
},
// 重写
async handleReset() {
this.ctx.clearRect(0, 0, this.width, this.height);
this.ctx.draw(true);
tempPoint = [];
},
// 获取canvas dom的宽高
getCanvasWH() {
return new Promise((resolve, reject) => {
uni
.createSelectorQuery()
.select(".mycanvas")
.boundingClientRect((data) => {
resolve({ width: data.width, height: data.height });
})
.exec();
});
},
// 取消
handleCancel() {
uni.navigateBack();
},
// 确认
handleConfirm() {
if (tempPoint.length === 0) {
console.log("请签名");
return;
}
uni.canvasToTempFilePath(
{
canvasId: "mycanvas",
success: (res) => {
const ctx = uni.createCanvasContext("camCacnvs", this);
ctx.translate(0, this.width);
ctx.rotate((-90 * Math.PI) / 180);
ctx.drawImage(res.tempFilePath, 0, 0, this.width, this.height);
ctx.draw();
uni.canvasToTempFilePath(
{
canvasId: "camCacnvs",
success: function (res) {
// 1. 获取当前页面栈实例(此时最后一个元素为当前页)
let pages = getCurrentPages();
// 2. 上一页面实例
// 注意是length长度,所以要想得到上一页面的实例需要 -2
// 若要返回上上页面的实例就 -3,以此类推
let prevPage = pages[pages.length - 2];
// 3. 给上一页面实例绑定getValue()方法和参数(注意是$vm)
prevPage.$vm.getTempFilePath(res.tempFilePath);
uni.navigateBack({
delta: 1,
});
},
},
this
);
},
},
this
);
},
},
};
</script>
<style lang="scss">
.container {
display: flex;
flex-direction: row;
}
.sign-box {
width: 80%;
height: 100%;
display: flex;
flex-direction: column;
text-align: center;
padding: 50rpx 0;
}
.sign-view {
height: 100vh;
}
.sigh-btns {
height: 100%;
margin: auto;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.btn {
margin: auto;
padding: 8rpx;
transform: rotate(90deg);
border: grey 1rpx solid;
}
.mycanvas {
width: 100%;
height: 100%;
background-color: #ececec;
}
.canvsborder {
border: 1rpx solid #333;
position: fixed;
top: 0;
left: 10000rpx;
}
</style>
utils
// 获取小程序标签的宽高
export const getCanvasWH = (querySelector, component) => {
return new Promise((resolve, reject) => {
component
.createSelectorQuery()
.select(querySelector)
.boundingClientRect((data) => {
resolve({ width: data.width, height: data.height });
})
.exec();
});
};