需求:在点击签名弹窗签名,点确定回显

1、封装一个.vue 文件,我是封装一个Signature.vue文件,放在components目录下
Signature.vue全部内容
javascript
<template>
<div class="signature">
<canvas class="signature-canvas" ref="canvas" @touchstart="startDrawing" @touchmove="draw" @touchend="stopDrawing"></canvas>
</div>
</template>
<script>
export default {
name: 'Signature',
data() {
return {
isDrawing: false,
signatureData: [],
};
},
methods: {
startDrawing(event) {
const canvas = this.$refs.canvas;
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
const x = (event.touches[0].clientX - rect.left) * scaleX;
const y = (event.touches[0].clientY - rect.top) * scaleY;
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(x, y);
this.isDrawing = true;
this.signatureData.push({ x: x / canvas.width, y: y / canvas.height });
},
draw(event) {
if (this.isDrawing) {
const canvas = this.$refs.canvas;
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
const x = (event.touches[0].clientX - rect.left) * scaleX;
const y = (event.touches[0].clientY - rect.top) * scaleY;
const ctx = canvas.getContext('2d');
ctx.lineTo(x, y);
ctx.stroke();
this.signatureData.push({ x: x / canvas.width, y: y / canvas.height });
}
},
stopDrawing() {
this.isDrawing = false;
},
clear() {
this.signatureData = [];
const canvas = this.$refs.canvas;
this.ctx = canvas.getContext('2d');
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
},
},
};
</script>
<style lang="less" scoped>
.signature {
position: relative;
}
.signature-canvas {
display: block;
border: 1px solid black;
margin: 10px;
width: calc(100% - 20px);
height: 200px;
}
</style>
在list.vue 文件引入使用 上述文件 components/Signature.vue,获取到的this.model.signList 就是签名
由很多坐标组成
javascript
<template>
<div class="van-doc-block">
<h2 class="van-doc-block-title">第二位维保人员签名确认<span>*</span></h2>
<van-cell-group inset>
<div class="signature-wrap" @click="openSignatureHandle('two')">
<div class="write-inner-wrap">
<div v-show="model.signList && model.signList.length" class="img-wrap">
<canvas class="signature-canvas" ref="outputCanvas"></canvas>
</div>
<div v-show="!model.signList || model.signList.length === 0" class="no-sign-wrap">点击此处进入签名区域</div>
</div>
</div>
</van-cell-group>
<van-popup v-model="signatureVisible" closeable position="bottom" :style="{ height: '45%' }">
<div class="signature-popup-wrap">
<Signature ref="signature"></Signature>
<div class="button-wrap">
<van-button type="default" native-type="button" @click="signatureClearHandle">清除</van-button>
<van-button type="primary" native-type="button" @click.stop="signatureOkHandle">确定</van-button>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import Signature from '@/components/Signature'; // 引入上述文件
export default {
components: { Signature },
data() {
return {
signatureVisible: false,
},
methods: {
signatureClearHandle() {
this.$refs['signature'].clear();
},
signatureOkHandle() {
const signatureData = lo.cloneDeep(this.$refs['signature'].signatureData);
this.$set(this.model, 'signList', signatureData);
this.drawSavedSignature(signatureData, 'outputCanvas');
},
drawSavedSignature(signatureData, canvasOut) {
this.$nextTick(() => {
const canvas = this.$refs[canvasOut];
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (signatureData && signatureData.length) {
ctx.beginPath();
ctx.moveTo(signatureData[0].x * canvas.width, signatureData[0].y * canvas.height);
for (let i = 1; i < signatureData.length; i++) {
const currentPoint = signatureData[i];
const previousPoint = signatureData[i - 1];
// 检查当前点和前一个点之间的距离,如果距离过大,则认为是新的笔画
const distance = Math.sqrt(Math.pow(currentPoint.x - previousPoint.x, 2) + Math.pow(currentPoint.y - previousPoint.y, 2));
if (distance > 0.1) {
ctx.moveTo(currentPoint.x * canvas.width, currentPoint.y * canvas.height);
} else {
ctx.lineTo(currentPoint.x * canvas.width, currentPoint.y * canvas.height);
}
}
ctx.stroke();
}
this.signatureVisible = false;
});
},
openSignatureHandle(type) {
this.showSignType = type;
this.$nextTick(() => {
const $signatureRef = this.$refs['signature'];
if ($signatureRef) {
this.$refs['signature'].clear();
}
});
this.signatureVisible = true;
},
}
}
}
</script>