小程序Canvas注意的问题
前言
当我们要做海报生成、描绘图片后保存这类需求时,往往离不开一个原生组件 —— canvas
;但canvas在文档中都是一些常规的操作,所以导致不能满足我们日常所要的需求,当我们实际开发的过程中,就会遇到各种各样的坑,所以我收集了下常见的问题,希望大家可以多多参考!~
1. canvas的异步执行
canvas 中很多 API 都是异步执行,这导致很多问题!
例如:
点击按钮保存图片为什么是空的等等…
canvasContext.drawImage
不能直接用网络图片(也不能用Base64),需要用wx.downloadFile(OBJECT)
下载成功后以 tempFilePath 的形式传给页面,res = {tempFilePath: ‘文件的临时路径’},用这个 tempFilePath 才能画图。wx.downloadFile(OBJECT)
是 异步 执行;wx.getImageInfo(OBJECT)
是 异步 执行;canvasContext.draw
异步。
解决办法:
利用判断或者加入定时器同样异步,确保画布生成后再进行保存操作。
2.生成图片时,图片模糊
我们都很容易想到解决方法:
使用wx.canvasToTempFilePath
生成图片后用image预览
但使用后会遇到两个问题:
- canvas无法使用display:none等方法隐藏(包括隐藏父容器),这会使得生成图片为空
解决方法:
<canvas class="canvas" canvas-id="invitationImage"></canvas>
<view class="invitation-main">
<view class="invitation-image">
<image class="image" src="{{imageUrl}}"></image>
</view>
<view class="invitation-operations">
<view class="operations-item">
<image src="{{baseUrl}}static/invitation/icon_qx.png"></image>
<view>取消</view>
</view>
<view class="operations-item">
<image src="{{baseUrl}}static/invitation/icon_wx.png"></image>
<view>微信好友</view>
</view>
<view class="operations-item">
<image catchtap="saveImage" src="{{baseUrl}}static/invitation/icon_bc.png"></image>
<view>保存到手机</view>
</view>
</view>
</view>
.canvas {
width: 750px;
height: 1334px;
}
.invitation-main{
display: flex;
align-content: center;
flex-direction: column;
justify-content: center;
height: 100vh;
background-color: #fff;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
将canvas放在容器外面,容器绝对定位占全屏已达到遮挡目的就行啦~
wx.canvasToTempFilePath
时必须draw()完成,否则生成图片也为空
drawImage: function(){
const ctx = wx.createCanvasContext('invitationImage')
// ctx.drawImage("/images/invitation/img_fx.png", 0, 0, 262, 466)
ctx.drawImage("/images/invitation/img_fx.png", 0, 0, 750, 1334)
ctx.rotate(-5 * Math.PI / 180)
// ctx.drawImage("/images/invitation/code.png", 92, 253, 57, 57)
ctx.drawImage("/images/invitation/code.png", 265, 723, 164, 164)
ctx.draw()
},
getImage: function(){
let that = this
console.log("getImage")
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 750,
height: 1334,
// width: 262,
// height: 466,
destWidth: 750,
destHeight: 1334,
canvasId: 'invitationImage',
success(res) {
console.log("tempFilePath",res.tempFilePath)
that.setData({
imageUrl: res.tempFilePath
})
},
fail() {
console.log("fail")
}
})
console.log("getImageEnd")
},
onLoad: function(options) {
this.drawImage()
},
onReady: function () {
let that=this
setTimeout(function () {
that.setData({
isOk: true
})
that.getImage()
}, 2000)
},
在文档加载时drawImage,完成时调用getImage。
注:延时操作确保异步执行,不然会出现时有时无
总结
因为canvas
的API方法很多都是异步操作的,所以当我们绘制我们想要的效果后,生成图片一定要加入为异步执行。
欢迎关注我的博客: https://blog.csdn.net/weixin_42323607
github地址: https://github.com/NurTuam
多多支持!本人会持续更新哒 ❤️