最近,用canvas画了很简单的一张图,里面只有文字和图片,绘制完成后把canvas转化成一张图片,用户可以下载到自己的手机上
遇到的问题:图片加载的时候会延迟绘图的过程,导致后面那张大背景图片绘画的时间比别的图片的时间长一点,遮盖其他的图片或者文字
先上图看看效果:
解决办法也很简单,就是把所有的图片先加载出来以后,再按照顺序依次绘图,直接看代码
备注:本代码使用vue写的,绘制图片的时候图片路径要用网络链接或者base64
先在dom中写个canvas
<canvas ref="canvaShare" width="414" height="1040"></canvas>
下面是代码逻辑
draw () { const that = this const canvas = this.$refs.canvaShare const ctx = canvas.getContext('2d') // 绘制 this.renderImage(ctx) // 把canvas转化成图片 setTimeout(function() { that.convertCanvasToImage(canvas) }, 500) }, renderImage (ctx) { const that = this // 这里使用promise.all(),不懂得可以百度一下,传入的是一个promise数组队列,这里就是加载完成的图片 // 这个地方可以有更优雅的写法 Promise.all([ this.loadImage(imgSrc.bg_url), this.loadImage(imgSrc.header_url), this.loadImage(imgSrc.waitness_url), this.loadImage(imgSrc.tyj_url), this.loadImage(imgSrc.dot_url), this.loadImage(imgSrc.saoma_url), this.loadImage(imgSrc.avatar_url), ]).then((imgs)=>{ // imgs就是图片队列 // 按照顺序依次绘制图片 ctx.drawImage(imgs[0], 0, 0, 414, 1040); ctx.drawImage(imgs[1], 93, 26, 239, 16); ctx.drawImage(imgs[2], 84, 144, 258, 198) ctx.drawImage(imgs[3], 150, 470, 115, 26) ctx.drawImage(imgs[4], 145, 524, 120, 115) ctx.drawImage(imgs[5], 140, 790, 134, 177) that.drawAvatar(ctx, imgs[6], 154, 532, 100) ctx.fillStyle = '#ffffff'; ctx.font = "24px AlibabaPuHuiTiB"; // userinfo.nickName 换绑定的用户信息 ctx.fillText("朽木白", 171, 680); ctx.fillStyle = 'rgba(255,255,255,0.6)'; ctx.font = "15px AlibabaPuHuiTiB"; ctx.fillText("回复“解决方案”获取媒体大脑优惠码", 82, 1000); }) }, // 预加载图片,最后返回一个promise对象 loadImage(url) { return new Promise((resolve)=>{ const img = new Image(); img.onload = ()=>resolve(img); img.src = url; }) }, // 绘制用户头像(圆形) drawAvatar (ctx, src, x, y, w) { //cavas 图片地址 位置x 位置y w宽高 const r = w / 2 ctx.save() ctx.arc(x + r, y + r, r, 0, 2 * Math.PI, false) ctx.clip() ctx.drawImage(src, x, y, w, w) ctx.restore() }, // 将canvas转化成image,才可以进行下载,必须等canvas绘制完成 convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL("image/png"); this.img = image.src }
知识点:canvas,promise.all(),将canvas转化成一张图片