项目逻辑介绍
- 用户填运单信息(类似寄快递),所有的信息都填写正确了,在最后提交运单的时候,弹出用 canvas 生产的电子签名画布
出现的问题
展示的效果图

canvas-id 写法
点击查看代码
<!-- wxml -->
<view class="mask" wx:if="{{isShowSign}}"></view>
<view class="canvaswrap" wx:if="{{isShowSign}}">
<view class="canvas-title jcsb font30">
托运签名 <text class="iconfont icon-close" bindtap='closeCanvas'></text>
</view>
<view class="canvas-tips">请用楷体签名,否则电子托运书将被退回</view>
<canvas class="canvas" canvas-id="myCanvas" disable-scroll bindtouchstart="bindtouchstart"
bindtouchmove="bindtouchmove"></canvas>
<view class="canvas-reset jcsb">
虚线框内签名 <text class="reset-text" bindtap="clearCanvas">重写</text>
</view>
<view class="canvas-btn">
<button class="btn" type="warn" plain bindtap='closeCanvas'>返回</button>
<button class="btn" type="warn" bindtap='export'>提交签名</button>
</view>
</view>
<!-- wxss -->
.mask {
position: absolute;
top: 0;
z-index: 100;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.canvaswrap {
position: fixed;
bottom: 0;
z-index: 100;
width: 100%;
padding: 26rpx 30rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 14rpx 14rpx 0px 0px;
}
.canvas-title {
padding-bottom: 24rpx;
}
.canvas-tips {
padding-bottom: 30rpx;
}
.icon-close {
font-size: 38rpx;
color: #CCCCCC;
}
.canvas {
width: 690rpx;
height: 400rpx;
border: 1px dotted #999999;
border-radius: 8rpx;
}
.signImg {
position: absolute;
z-index: 200;
width: 690rpx;
height: 400rpx;
}
.canvas-reset {
padding: 24rpx 0 30rpx;
font-size: 26rpx;
color: #999;
}
.reset-text {
padding: 4rpx 22rpx;
border: 1px solid #999999;
border-radius: 20rpx;
font-size: 24rpx;
}
.canvas-btn {
display: flex;
justify-content: space-between;
}
// javascript
Page({
data: {
canvas: null,
ctx: null,
width: '',
height: 200,
},
// 生成画布
createCanvas() {
const that = this
let query = wx.createSelectorQuery();
query.select('#myCanvas').boundingClientRect();
query.exec(function (rect) {
let width = rect[0] && rect[0].width;
let height = rect[0] && rect[0].height;
const ctx = wx.createCanvasContext('myCanvas')
ctx.setLineWidth(3)
ctx.setFontSize(20)
ctx.draw()
that.setData({
width,
height,
ctx,
});
});
},
/** 签名 */
// 记录开始点
bindtouchstart(e) {
let that = this
if (!that.data.ctx) { // 解决安卓手机不能签名
that.createCanvas()
}
that.data.ctx.moveTo(e.changedTouches[0].x, e.changedTouches[0].y)
that.setData({
isBlank: false
})
},
// 记录移动点,刷新绘制
bindtouchmove(e) {
const ctx = this.data.ctx
ctx.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);
ctx.stroke();
ctx.draw(true);
ctx.moveTo(e.changedTouches[0].x, e.changedTouches[0].y);
},
// 清空画布
clearCanvas() {
const that = this
that.setData({
signImg: '',
firstUserSign: ''
})
const ctx = that.data.ctx
ctx.clearRect(0, 0, that.data.width, that.data.height);
ctx.draw();
ctx.setLineWidth(2)
ctx.setFontSize(20)
ctx.draw()
that.createCanvas()
},
// 导出图片
export () {
const that = this;
const {
ctx,
width,
height,
isBlank,
time,
} = that.data
let {
params,
header
} = that.notBlank()
if (isBlank) { // 空白画布
wx.showModal({
title: '提示',
content: '立即提交前,请签名!',
showCancel: false
})
return
}
wx.showModal({
title: '提示',
content: '是否要提交订单?',
success(qRes) {
if (qRes.confirm) {
wx.showLoading({
title: '提交中...',
mask: 'true',
})
// 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
ctx.draw(true, setTimeout(function () {
wx.hideLoading({
success: () => {
// 画布生成图片
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: width,
height: height,
destWidth: width,
destHeight: height,
fileType: 'png',
canvasId: 'myCanvas',
success(ctxRes) {
// 隐藏签名框
that.setData({
isShowSign: false
})
// 图片转成base64
wx.getFileSystemManager().readFile({
filePath: ctxRes.tempFilePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: result => { //成功的回调
params.saveCode = 'SUBMIT'
params.signImgStr = config.base64 + result.data
// 请求
util.requestPost('ship_ebook/save_prestore', params, 'POST', header)
.then((resP) => {
if (resP.data.retCode == 200) {
wx.showToast({
title: '提交成功'
})
that.resetInfo()
} else {
wx.showToast({
title: resP.data.retMsg,
icon: 'none'
})
}
})
.catch((err) => {
wx.showModal({
title: '提示',
content: err.data.retMsg,
showCancel: false
})
})
that.setData({
base64Img: config.base64 + result.data
})
}
})
}
})
}
})
}, time))
}
}
})
},
})
微信开发者工具提示
接口停止维护
canvas 2d 写法
点击查看代码
<!-- wxml -->
<canvas class="canvas" type="2d" id="myCanvas" disable-scroll bindtouchstart="bindtouchstart" bindtouchmove="bindtouchmove"></canvas>
// javascirpt
/** 签名 */
// 记录开始点
bindtouchstart(e) {
let that = this
const ctx = this.data.ctx
ctx.beginPath();
ctx.moveTo(e.changedTouches[0].x, e.changedTouches[0].y)
that.setData({
isBlank: false
})
},
// 记录移动点,刷新绘制
bindtouchmove(e) {
const ctx = this.data.ctx
ctx.lineTo(e.changedTouches[0].x, e.changedTouches[0].y)
ctx.stroke()
},
// 清空画布
clearCanvas() {
const that = this
that.setData({
signImg: '',
firstUserSign: ''
})
that.data.ctx.clearRect(0, 0, this.data.width, this.data.height);
},
// 导出图片
export () {
const that = this;
const {
ctx,
width,
height,
isBlank,
time,
canvas
} = that.data
let {
params,
header
} = that.notBlank()
if (isBlank) { // 空白画布
wx.showModal({
title: '提示',
content: '立即提交前,请签名!',
showCancel: false
})
return
}
wx.showModal({
title: '提示',
content: '是否要提交订单?',
success: (qRes) => {
if (qRes.confirm) {
// 隐藏签名框
that.setData({
isShowSign: false
})
wx.showLoading({
title: '提交中...',
mask: 'true',
})
setTimeout(() => {
wx.hideLoading({
success: () => {
let cImg = canvas.toDataURL()
params.saveCode = 'SUBMIT'
params.signImgStr = cImg
// 请求
util.requestPost('ship_ebook/save_prestore', params, 'POST', header)
.then((resP) => {
if (resP.data.retCode == 200) {
wx.showToast({
title: '提交成功'
})
that.resetInfo()
} else {
wx.showToast({
title: resP.data.retMsg,
icon: 'none'
})
}
})
.catch((err) => {
wx.showModal({
title: '提示',
content: err.data.retMsg,
showCancel: false
})
})
that.setData({
base64Img: cImg
})
}
})
}, time)
}
}
})
},