效果图
1、点击横线
2、展示弹窗
3、完成签名
signature组件代码
JS
var cxt = null;
var arrx = [];
var arry = [];
var canvasw = 0;
var canvash = 0;
Component({
properties: {},
data: {
signatureImg: ""
},
methods: {
createdCanvas() {
wx.showLoading({
title: '加载中...',
mask: true
})
cxt = wx.createCanvasContext('canvas', this);
cxt.beginPath();
var query = wx.createSelectorQuery().in(this).select('.handCenter');
query.boundingClientRect(rect => {
canvasw = rect.width / 2;
canvash = rect.height / 2;
wx.hideLoading()
}).exec();
},
canvasIdErrorCallback(e) {
console.error(e.detail.errMsg)
},
canvasStart(e) {
arrx.push(e.changedTouches[0].x);
arry.push(e.changedTouches[0].y);
},
canvasMove(e) {
let len = arrx.length;
cxt.moveTo(arrx[len - 1], arry[len - 1]);
arrx.push(e.changedTouches[0].x);
arry.push(e.changedTouches[0].y);
cxt.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);
cxt.setLineWidth(4);
cxt.setLineCap('round');
cxt.stroke();
cxt.draw(true);
},
getImg() {
if (arrx.length == 0) {
wx.showModal({
title: '提示',
content: '签名内容不能为空!',
showCancel: false
});
return false;
};
wx.showLoading({
title: '签名生成中..',
mask: true
})
let that = this;
wx.canvasToTempFilePath({
canvasId: 'canvas',
success: function (res) {
that.setData({
signatureImg: res.tempFilePath
})
wx.hideLoading();
console.log();
that.triggerEvent("canvasDis", {
signatureImg: res.tempFilePath
})
}
}, this)
},
cleardraw() {
arrx = [];
arry = [];
cxt.clearRect(0, 0, canvasw, canvash);
cxt.draw();
this.setData({
signatureImg: ''
});
},
canvasEnd(e) {}
},
ready() {
this.createdCanvas()
}
})
WXML
<!-- 签名组件 -->
<view class="wrapper">
<view class="title">
请在下方灰色框内签名:
</view>
<view class="handCenter">
<canvas class="canvas" id="canvas" canvas-id="canvas" disable-scroll="true" bindtouchstart="canvasStart" bindtouchmove="canvasMove" binderror="canvasIdErrorCallback">
</canvas>
</view>
<view class="handBtn">
<button catchtap="cleardraw" class="delBtn">清空</button>
<button catchtap="getImg" class="subBtn">完成</button>
</view>
</view>
CSS
.wrapper{
position: fixed;
top:20rpx;
bottom: 0;
right: 0;
left: 0;
box-sizing: border-box;
background-color: #fff;
z-index: 99999;
overflow-y: auto;
}
.title{
margin: 20rpx;
border-radius:16rpx;
}
.handCenter{
box-sizing: border-box;
width: 100%;
background-color: rgba(228, 228, 228, 0.39);
}
canvas {
width:100%;
height: 1000rpx;
margin:auto;
}
.overImg{
width: 200rpx;
height: 200rpx;
}
.handCenter {
box-sizing: border-box;
}
.handBtn {
height: 100rpx;
display: flex;
align-content: space-between;
align-items: center;
margin:40rpx 0;
padding: 0 20rpx;
}
.delBtn {
width: 40%;
color: #666;
}
.subBtn {
width: 40%;
background: #008ef6;
color: #fff;
}
button{
font-size: 34rpx;
}
父组件引用代码
WXML
<view>(签名)</view>
<view wx:if="{{!signatureImg}}" class="signature_line" bindtap="signature" data-index="{{index}}"></view>
<image class="signature_img" wx:if="{{signatureImg}}" src="{{signatureImg}}" bindtap="signature"></image>
<page-container show="{{isOpen}}" position="{{containerType}}" bind:afterleave="closeContainer">
<view wx:if="{{containerType==='center'}}">
<signature bindcanvasDis="handlChangeCanvasShow"></signature>
</view>
</page-container>
JS
data:{
containerType: 'bottom',
isOpen: false,
signatureImg: ''
}
signature: function (e) {
if(this.data.isConfirm){
return
}
let {
index
} = e.currentTarget.dataset
this.setData({
containerType: 'center',
isOpen: true
})
},
closeContainer: function () {
this.setData({
isOpen: false,
containerType: ''
})
},
handlChangeCanvasShow(e) {
let that = this
if (e.detail.signatureImg != '') {
that.setData({
signatureImg: e.detail.signatureImg
})
that.closeContainer()
}
},
JSON
"usingComponents": {
"signature":"../../components/signature/signature"
},