900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 小程序canvas循环绘制内容的问题

小程序canvas循环绘制内容的问题

时间:2019-11-22 21:55:32

相关推荐

小程序canvas循环绘制内容的问题

这次的业务逻辑中要用到小程序canvas。

这个canvas的要求是一段文字中间会加入一张图片然后在接下去写一段文字内容。并且文字和图片是随机出现的,因此只能用for循环来做。这里有一个问题就是canvas绘制文字的速度比绘制图片的速度快很多,一个for循环之后,for循环中的文字绘制已经执行完了但是,for循环中的图片还没有绘制好,就已经执行了for循环外面的context.draw()方法绘制好了canvas。这样图片就没有绘制上去。

解决思路:等待每一个for循环中的无论文字还是图片绘制完成之后在执行下一个for循环。

这里我用的是es6的async和await

代码:

async drawCanvas () {wx.showLoading({title: '加载中',})const context = wx.createCanvasContext('Canvas')const w = (wx.getSystemInfoSync().screenWidth / 375)//设备宽度比例let that = thislet row = ''//每行文字let H = w * (250/that.data.imgWidth) * that.data.imgHeight//canvas主图高let startHeight = 0//开始画的高度let h = 0context.setFillStyle('#ffffff')//画背景色context.fillRect(0, 0, 500, 816)//画背景色//引用本地图片context.drawImage(that.data.img,0,0,w * 250,H)//引入图片context.drawImage('路径','X轴距离','Y轴距离','引入图片长','引入图片宽')startHeight = H + 11context.setFontSize(w * 11);//设置文字大小context.setFillStyle("#333333");//设置文字颜色context.fillText(this.data.title,w * 13, w * (H + 12));//文字内容和坐标位置for (let j = 0;j < that.data.content.detail.length;j++) {if (that.data.content.detail[j].type == 1) {//画文字let pItem = that.data.content.detail[j].content.word.split('')for (let i = 0;i < pItem.length;i++) {row += pItem[i]if (context.measureText(row).width >= w * 224) {//拼接每一行的字符串if (w * (18 + startHeight) >= 390) {//当篇幅太大所能支持的最大行数row = row.substring(0,5) + '...'await context.setFontSize(w * 9);await context.setFillStyle("#333333");await context.fillText(row,w * 13,w * (18 + startHeight),w * 224);startHeight += 15break;}await context.setFontSize(w * 9);await context.setFillStyle("#333333");await context.fillText(row,w * 13, w * (18 + startHeight),w * 224)startHeight += 15row = ''}if (i == pItem.length - 1) {//最后一次且不到最大篇幅时画上去await context.setFontSize(w * 9);await context.setFillStyle("#333333");await context.fillText(row,w * 13, w * (18 + startHeight),w * 224);startHeight += 15row = ''}}}else if (that.data.content.detail[j].type == 0) {//画图if (startHeight > 390) {return}let img = that.data.content.detail[j].content.imgawait new Promise(function (resolve,reject) {wx.getImageInfo({src: img,success: async res => {h = (224/res.width) * res.heightresolve()}})}).then(async function () {await context.drawImage(img,w * 13,w * (startHeight + 10),w * 224,w * h)startHeight = startHeight + h + 5})}}context.draw()//生成canvas图片that.setData({isCanvas : true})wx.hideLoading()},

其中绘制图片的时候需要回去到每一张图片的高度和宽度信息来进行等比缩放这里,这里就用到了wx的wx.getImageInfo()这个api,这里的成功回调是个传入的回调函数,await不起效果。这里我直接实例化一个promise将成功回调函数中的操作方到了then中。

最终效果:

总结:for循环中默认不会等待前一个循环中的所有程序都运行结束才去下一个for循环,而是直接不等待循环中的异步操作结束就像进入下一个循环。那么遇到for循环中后一个循环依赖前一个循环的结果这种情况async和await是一个很简便的处理方式。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。