<template>
<div class="indexs">
<!-- 签名开始-->
<div class="signature" v-if="showSignature" @click.stop>
<div class="signature_content" style="position: relative;">
<div style="margin-top: 20px;">
<div style="display: flex;align-items: center;margin-left: 20px;">
<span>客户签名:</span>
<div v-if="signImage"
style="width: 80px;height: 40px;border: 1px dashed red; display: flex;align-items: center;justify-content: center;margin-left: 10px;">
<van-image v-if="signImage" :src="signImage" width="40px" height="80px"
style=" object-fit: contain" />
</div>
</div>
</div>
<div style="margin-top: 20px;">
<div style="display: flex;align-items: center;margin-left: 20px;height:20px;line-height: 20px;">
<span>签名日期:</span>
<span style="color: #666666;margin-left: 10px;height:20px;line-height: 20px;">{{signDate}}</span>
</div>
</div>
</div>
<div class="signature_confrim" @click="signImage?signatureConfrim():startSignAndClear()">
{{signImage?'完成签署':'点击签名'}}
</div>
</div>
<div class="canvas_container" v-show="startSign">
<canvas id="canvas" @touchstart="canvasDown($event)" @mousedown="canvasDown($event)" @mouseup="canvasUp($event)"
@mousemove="canvasMove($event)" @touchend="canvasUp($event)" @touchmove="canvasMove($event)">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas>
<div
style="position: absolute;top: 0px;left:20px;padding:10px 20px;">
请投保人/被保险人张文签字
</div>
<div class="signature_control">
<span @click="signBack" style="color: #999999; padding:5px">返回</span>
<span @click="clearCanvas" v-show="hasSign">重写</span>
<span @click="hasSign?signatureComplete():()=>{}" style="background-color:#999999">提交</span>
</div>
</div>
<!-- 签名结束 -->
</div>
</template>
<script>
let beginPoint = null;
let points = []; // 存放操作点数组 为了用二次贝塞尔曲线画圆滑的线
export default {
data(){
return {
showSignature:true,
signImage:'',
signDate:'',
startSign:true,
hasSign:true,
context: {}, //画布对象
preDrawAry: [],// 存储当前表面状态数组-上一步
nextDrawAry: [],// 存储当前表面状态数组-下一步
middleAry: [],// 中间数组
canvasMoveUse: false,
canCompleteSignature: false,
config: {
lineWidth: 2,
lineColor: '#000000',
shadowBlur: 1
},
}
},
mounted(){
this.showSign()
},
methods:{
// 签名确认
signatureConfrim() {
console.log("签字", this.canCompleteSignature)
if (!this.canCompleteSignature) {
this.$toast({
message: "未签字,请签字"
})
return
}
this.showSignature = false;
this.canCompleteSignature = false;
},
startSignAndClear() {//点击签名
this.startSign = true;
this.clearCanvas();
},
//mousedown
canvasDown(e) {
this.canvasMoveUse = true
points = [];
const {
canvasX,
canvasY
} = this.getPos(e);
console.log('canvasX', canvasX, 'canvasY', canvasY)
points.push({
x: canvasX,
y: canvasY
});
beginPoint = {
x: canvasX,
y: canvasY
};
this.setCanvasStyle() //提前设置好 删除了选择版
// 清除子路径
this.context.beginPath()
this.context.moveTo(canvasX, canvasY)
// 当前绘图表面状态
const preData = this.context.getImageData(0, 0, 600, 400)
// 当前绘图表面进栈
this.preDrawAry.push(preData)
},
// mouseup
canvasUp() {
if (points.length > 3) {
const lastTwoPoints = points.slice(-2);
const controlPoint = lastTwoPoints[0];
const endPoint = lastTwoPoints[1];
this.drawLine(beginPoint, controlPoint, endPoint);
if (!this.hasSign) {
this.hasSign = true
}
}
beginPoint = null;
const preData = this.context.getImageData(0, 0, 600, 400)
if (!this.nextDrawAry.length) {
// 当前绘图表面进栈
this.middleAry.push(preData)
} else {
this.middleAry = []
this.middleAry = this.middleAry.concat(this.preDrawAry)
this.middleAry.push(preData)
this.nextDrawAry = []
}
this.canvasMoveUse = false
},
getPos(e) { //获取操作位置的横竖坐标
const canvas = document.querySelector('#canvas');
let currentX, currentY, t = e.target
if (this.isPc()) {
currentX = e.clientX - t.parentNode.offsetLeft
currentY = e.clientY - t.parentNode.offsetTop
} else {
if (e.changedTouches && e.changedTouches.length > 0 && e.changedTouches[0].clientX) {
currentX = e.targetTouches[0].clientX - canvas.offsetLeft
currentY = e.targetTouches[0].clientY - canvas.offsetTop
} else {
currentX = e.clientX - t.parentNode.offsetLeft
currentY = e.clientY - t.parentNode.offsetTop
}
}
return {
x: currentX,
y: currentY
}
},
drawLine(beginPoint, controlPoint, endPoint) {
this.context.beginPath();
if (beginPoint && beginPoint.x) {
this.context.moveTo(beginPoint.x, beginPoint.y);
this.context.quadraticCurveTo(controlPoint.x, controlPoint.y, endPoint.x, endPoint.y);
this.context.stroke();
this.context.closePath();
}
},
//mousemove
canvasMove(e) {
if (this.canvasMoveUse) {
const {
x,
y
} = this.getPos(e);
points.push({
x: x,
y: y
});
if (points.length > 3) {
const lastTwoPoints = points.slice(-2);
const controlPoint = lastTwoPoints[0];
const endPoint = {
x: (lastTwoPoints[0].x + lastTwoPoints[1].x) / 2,
y: (lastTwoPoints[0].y + lastTwoPoints[1].y) / 2,
}
this.drawLine(beginPoint, controlPoint, endPoint);
beginPoint = endPoint;
if (!this.hasSign) {
this.hasSign = true
}
}
}
e.preventDefault();
},
signBack() {
this.startSign = false;
},
// 设置绘画配置
setCanvasStyle() {
this.context.lineWidth = this.config.lineWidth
this.context.shadowBlur = this.config.shadowBlur
this.context.shadowColor = this.config.lineColor
this.context.strokeStyle = this.config.lineColor
this.context.lineJoin = 'round';
this.context.lineCap = 'round';
},
clearCanvas() {
const canvas = document.querySelector('#canvas')
this.context.clearRect(0, 0, canvas.width, canvas.height);
points = [];
if (this.hasSign) {
this.hasSign = false
}
},
// 签名完成
signatureComplete() {
this.startSign = false;
if (points.length > 3) {
this.canCompleteSignature = true;
} else {
this.canCompleteSignature = false;
}
this.getImage();
this.canvasUp();
const canvas = document.querySelector('#canvas')
this.context.clearRect(0, 0, canvas.width, canvas.height);
},
// 生成图片
getImage() {
const canvas = document.querySelector('#canvas')
console.log("getImage", points, points.length)
if (points.length > 3) {
this.signImage = canvas.toDataURL('image/png')
} else {
this.signImage = ""
}
},
isPc() {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
let flag = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false
break
}
}
return flag
},
showSign() {
this.signDate = this.$timeUtils.getDate();
this.showSignature = true;
const canvas = document.querySelector('#canvas')
this.context = canvas.getContext('2d')
this.initDraw()
this.setCanvasStyle()
this.anti();
this.signImage = ""
},
initDraw() {
const preData = this.context.getImageData(0, 0, 600, 400)
// 空绘图表面进栈
this.middleAry.push(preData)
},
// 当在屏幕中移动时即开始绘制准备
anti() {
const canvas = document.querySelector('#canvas')
console.log(document.body.clientWidth,"啊哈哈")
canvas.style.width = document.body.clientWidth;
canvas.style.height = document.body.clientHeight;
canvas.height = document.body.clientHeight;
canvas.width = document.body.clientWidth;
},
}
}
</script>
<style lang="scss" scoped>
.indexs{
/* 签字 */
width: 100%;
height: 100%;
.signature {
width: 69%;
height: 100%;
background: #FFFFFF;
border-radius: 20px 20px 0px 0px;
position: absolute;
bottom: 0;
left: 0;
.signature_content {
width: calc(100% - 40px);
height: calc(100% - 100px);
padding: 10px 20px;
background: #EBEBEB;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
.signature_confrim {
width: calc(100% - 76px);
height: 48px;
background: linear-gradient(180deg, #FF8A2A 0%, #FE702B 100%);
border-radius: 24px;
margin-left: 38px;
margin-top: 10px;
font-size: 17px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 48px;
text-align: center;
}
}
.canvas_container {
width: calc(69% - 4px);
height: calc(100% - 4px);
border: 2px dashed #979797;
position: absolute;
left: 0;
top: 0;
background-color: #ffffff;
overflow: hidden;
-webkit-overflow-scrolling: touch;
.signature_control {
position: absolute;
left: 35px;
bottom: 220px;
display: flex;
align-items: center;
margin-top: 10px;
width: 220px;
padding: 10px 20px;
justify-content: space-evenly;
transform: rotate(90deg);
transform-origin: left;
}
.signature_control span:nth-child(1) {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
}
.signature_control span:nth-child(2) {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #3E7DFE;
}
.signature_control span:nth-child(3) {
font-size: 17px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
width: 96px;
height: 49px;
line-height: 49px;
text-align: center;
background: linear-gradient(180deg, #FF8A2A 0%, #FE702B 100%);
border-radius: 24px;
}
}
}
</style>