项目需要上传图片并对图片做缩放处理,图片缩放需要使用canvas组件来实现。我们决定将上传及缩放功能做在一起,封装成一个独立的小程序组件,方便项目中随时使用,但总是报错,修正之前的问题代码如下
js
lifetimes: {
created: function(){
this.cavid = this.uniqId + '_cav' // 随机值
},
attached: function() {
this.setData({
canvasId: this.cavid // 答案是它,不能这样为canvas-id设置值
})
}
...
...
}
// 一定是在ready后由事件方法触发执行
drawImg(tempFilePaths, canvasWidth, canvasHeight){
let that = this
let cavsid = this.cavid
let ctx = wx.createCanvasContext(cavsid);
ctx.drawImage(tempFilePaths, 0, 0, canvasWidth, canvasHeight)
ctx.draw()
setTimeout(() => {
wx.canvasToTempFilePath({
canvasId: cavsid,
success: function (res) {
....
}
}, that)
})
}
wxml
<canvas
canvas-id="{{canvasId}}"
style="width:{{canvasWidth}}px; height:{{canvasHeight}}px; position: absolute;left:-500px;top:-500px;"
></canvas>
错误1
canvasToTempFilePath: fail canvas is empty
createCanvasContext
是依据canvas-id
来找到对应的canvas组件,如此看来我们在生命周期方法中定义的canvasId
不能被正确捕获,才造成以上错误
解决方案
- 将
canvasId
设置为常量字符串 - 将
canvasId
在data属性中设置
properties: {
dataSource: Object,
},
data: {
canvasId: lib.suid('canvas_') // 在data属性里这里设置
},
behaviors: [],
如此解决canvasToTempFilePath: fail canvas is empty
的错误
错误2
canvasToTempFilePath
输出为空白
通过canvasToTempFilePath
方法能够通过canvas重绘图片,为什么输出为空白。这个问题主要还是文档太坑,将canvas组件封装为组件需要对canvas的特定方法绑定上下文context,才能正常使用。
解决方案
// 一定是在ready后由事件方法触发执行
drawImg(tempFilePaths, canvasWidth, canvasHeight){
let that = this
let cavsid = this.cavid
let ctx = wx.createCanvasContext(cavsid, that);
ctx.drawImage(tempFilePaths, 0, 0, canvasWidth, canvasHeight)
ctx.draw()
setTimeout(() => {
wx.canvasToTempFilePath({
canvasId: cavsid,
success: function (res) {
....
}
}, that)
})
}
- createCanvasContext
- canvasToTempFilePath
注意上述两个方法的第二参数都为that
,指向组件自身的this
,应该就能正常输出图片了
偶现输出空白图有遇到过吗?
https://developers.weixin.qq.com/community/develop/doc/0006246d8d8a004f903a43a235e400
是的,自定义组件里使用canvas压缩图片遇到了很多坑,因为不报错,官方文档又很烂,所以很难定位到出问题的api。
自定义组件里使用canvas需要特别注意那两个api。我现在还有个未解决的问题是为啥我canvasToTempFilePath导出的图片又小又模糊?
每次用小程序的提供的api,免不了磕磕碰碰