前言
- 之前做了一个需求,要实现【微信小程序】实现【电子签名】的效果,所以就直接开始埋头写,然后上线了。上线之后却是有问题,这边的话对开发过程中遇到的问题进行总结记录一下!
初始开发
- 刚开始的时候,遇到需要绘制电子签名的功能,咱就是直接一个百度,到处搜索别人是怎么做的,后面看大家大体上都是通过canvas进行绘制的。所以就直接通过canvas直接写起来了,写完之后功能实现没啥问题,测试却告诉我他测试过程中画着画着有闪退的问题。。。然而我这边没法复现出来,测试也是偶现的状态,一下子就不知道是什么问题,因为考虑到这个功能可能客户初始也没什么人用,就先上线一下吧~
- 【问题1】然而,一上线,就懵了,这个绘制的canvas弹窗直接就卡住,根本出不来,要等到5s左右之后才出现且所有页面直接卡死,然后就开始排查,发现这个
const context = wx.createCanvasContext('myCanvas')
api已经不用了,有点问题 - 【问题2】然后就还有另一个问题,就是提交的时候,进程阻塞,一直处于转圈的情况.排查之后是因为要把加密的图片流传给后端,要先下载图片。然后图片是http格式的,不是合法域名
问题解决方案
- 【问题1】:对于canvas绘制的效率问题,微信官方文档已经给出了方案使用
<canvas type='2d'></canvas>
的绘图方式,所以将绘图方式改动就可。 - 【问题2】:对于提交时转圈问题,解决方案就是让后端将图片路径改为https的,然后再在微信公众平台进行配置一下域名就可以了。
- 上线之后,finally, 问题修复了.
代码实现
这边贴一下主要的代码,如需要完整代码,可联系我~
// 有竖屏和横屏绘制,可切换
// 绘制时如背景页面是长页面可滑动的情况,滑动画布会移动, 可设置最外层容器catchtouchmove="true"
<canvas type='2d' id="canvas-vertical" disable-scroll="true" class="cavas" catchtouchstart="catchtouchstart" catchtouchmove="catchtouchmove" catchtouchend="catchtouchend"></canvas>
<canvas type='2d' id="canvas-level" class="cavas" catchtouchstart="catchtouchstart" catchtouchmove="catchtouchmove" catchtouchend="catchtouchend"></canvas>
初始化画布对象
initCanvas(canvasId = 'canvas-vertical') {
this.canvasId = canvasId
const nodeId = '#' + canvasId
wepy.nextTick(() => { // 获取节点问题(需要延时获取)
wx.createSelectorQuery()
.select(nodeId) // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec(res => {
console.log(res, 'res------')
// Canvas 对象
const canvas = res[0].node
this.canvas = canvas
// Canvas 画布的实际绘制宽高
const renderWidth = res[0].width
const renderHeight = res[0].height
// Canvas 绘制上下文
const ctx = canvas.getContext('2d')
this.ctx = ctx
// 初始化画布大小
const dpr = wx.getWindowInfo().pixelRatio
canvas.width = renderWidth * dpr
canvas.height = renderHeight * dpr
this.width = canvas.width
this.height = canvas.height
ctx.scale(dpr, dpr)
this.isDrawed = false
})
})
}
绘制过程中记录绘制路径,进行绘制
catchtouchstart(e) {
// 竖屏与横屏绘画位置计算
if (this.canvasId === 'canvas-vertical') {
this.ctx.moveTo(e.changedTouches[0].clientX - e.currentTarget.offsetLeft, e.changedTouches[0].clientY - e.currentTarget.offsetTop)
} else {
this.ctx.moveTo(e.changedTouches[0].clientX, e.changedTouches[0].clientY)
}
},
catchtouchmove(e) {
// if (this.drawState == "stop") { return }
// this.drawState = "ing"
if (e.touches.length > 1) {
return
}
this.ctx.strokeStyle = '#000000'
this.ctx.lineWidth = 3
this.ctx.lineCap = 'round'
this.ctx.lineJoin = 'round'
if (this.canvasId === 'canvas-vertical') {
this.ctx.lineTo(e.changedTouches[0].clientX - e.currentTarget.offsetLeft, e.changedTouches[0].clientY - e.currentTarget.offsetTop)
} else {
this.ctx.lineTo(e.changedTouches[0].clientX, e.changedTouches[0].clientY)
}
if (this.canvasId === 'canvas-vertical') {
this.ctx.moveTo(e.changedTouches[0].clientX - e.currentTarget.offsetLeft, e.changedTouches[0].clientY - e.currentTarget.offsetTop)
} else {
this.ctx.moveTo(e.changedTouches[0].clientX, e.changedTouches[0].clientY)
}
this.ctx.stroke()
},
绘制结束,生成图片
canvasToImg() {
const id = this.canvasId
let picUrl
// if (this.drawState == "init") { return }
const that = this
this.ctx.fillStyle = '#F7F7F7'
if (this.isDrawed) {
setTimeout(() => {
wx.canvasToTempFilePath({
fileType: 'png',
canvas: this.canvas,
success: res => {
const obj = {}
// 让后端进行图片的翻转,因为横屏时绘制的签名是横的
if (that.canvasId === 'canvas-vertical') {
obj.isFlip = 0
obj.angle = 0
} else {
obj.isFlip = 1 // 是否翻转
obj.angle = -90 // 翻转角度
}
uploadPicture(res.tempFilePath, 'relation', obj).then(res => {
// that.drawState = "stop"
that.isShow = false
picUrl = res
// that.clearRefer()
that.$apply()
that.$emit('ok', res)
})
}
})
})
} else {
this.$toast('请进行签名')
}
},
结语
大体的实现就是差不多如上所述。今天还是一个情人节哎,祝所有天下的有情人💕都能终成眷属,也祝所有的单身狗😼可以早日找到自己的意中人~ 完结撒花~