微信小程序之canvas绘制海报分享到朋友圈
绘制canvas内容
首先,需要写一个canvas标签,给canvas-id命名为shareBox
1 <canvas canvas-id="shareBox"></canvas>
其次,我们就要根据需求(效果图如下)在canvas上面绘制内容了,我这里canvas指的是红框里面的内容
然后开始绘制内容啦,先定义一个绘制内容的方法:drawImage
1 drawImage() { 2 //绘制canvas图片 3 var that = this; 4 console.log(that.data.userInfo); 5 var qrPath = that.data.qrcode_temp; //小程序码本地路径 6 var imgLogo = that.data.photoTempath; //微信头像本地路径 7 var banner = that.data.banner_temp; //展会bannertu的本地路径 8 var bgimg = "/images/bg4@2x.png"; //背景图 9 10 //创建一个canvas对象 11 const ctx = wx.createCanvasContext('shareBox', this); 12 13 ctx.setFillStyle("white"); 14 var canvasWidth = that.data.width; //自适应宽 15 var canvasHeight = that.data.height - that.data.footHeight; //自适应高 (减去底部高度) 16 17 console.log(canvasWidth + "--" + canvasHeight) 18 ctx.fillRect(0, 0, canvasWidth, canvasHeight); 19 ctx.drawImage(bgimg, 10, 10, canvasWidth-20, canvasHeight-20); 20 21 //绘制分享标题 22 23 ctx.setFontSize(15); 24 ctx.setFillStyle('#000'); 25 ctx.setTextAlign('left'); 26 ctx.fillText(that.data.userInfo.nickName+"邀请您一起参加", 110, 50, canvasWidth-135); 27 var title = that.data.exhibitionDetail.ExName; 28 if (title.length > 17) { 29 var a = title.substr(0, 17); 30 var b = title.substr(17, title.length); 31 ctx.fillText(a, 110, 70, canvasWidth - 135); 32 ctx.fillText(b, 110, 90, canvasWidth - 135); 33 }else{ 34 ctx.fillText(title, 110, 70, canvasWidth - 135); 35 } 36 37 38 //绘制标题 39 ctx.setFontSize(15); 40 ctx.setTextAlign('left'); 41 ctx.setFillStyle('#000'); 42 ctx.fillText(title, 30, 250, canvasWidth - 60); 43 ctx.fillText(title, 30, 250, canvasWidth - 60); 44 45 //绘制时间 46 ctx.setFontSize(12); 47 ctx.setTextAlign('left'); 48 ctx.setFillStyle('#333'); 49 var time = that.data.exhibitionDetail.StartTime+"至"+ that.data.exhibitionDetail.EndTime; 50 ctx.fillText(time, 30, 270, canvasWidth - 60); 51 52 //绘制地点 53 ctx.setFontSize(12); 54 ctx.setTextAlign('left'); 55 ctx.setFillStyle('#333'); 56 var place = that.data.exhibitionDetail.Place; 57 ctx.fillText(place, 30, 290, canvasWidth - 60); 58 59 //绘制圆形头像 60 ctx.save(); 61 ctx.beginPath(); 62 ctx.arc(65, 65, 35, 0, 2 * Math.PI,false); 63 ctx.setStrokeStyle('#eee') 64 ctx.stroke(); //画了背景的话要先画圆在裁剪才能有圆形图片 65 ctx.clip(); //裁剪 66 ctx.drawImage(imgLogo, 30, 30, 70, 70); 67 ctx.restore(); 68 69 70 //绘制banner图 71 // ctx.drawImage(banner, 15, 120, 150, 315); 72 73 //绘制小程序码图 74 //ctx.drawImage(banner, 70, 310, 100, 100); 75 76 ctx.draw(); 77 78 }
代码解释:
一、关于画圆形图片
这里遇到的问题是: 绘制圆形图片的时候需要裁剪,一开始我没有绘制背景,直接裁剪的(就是没有ctx.stroke()这一步也是能成功的画出圆形图片的)。
之后加了背景图之后,就无效了,查看了许多资料得知有背景图的情况下,需要先把圆画出来,再裁剪才行,就是我上诉代码中红色备注中的写法。
二、关于网络图片的应用
上述代码中有注释写的是本地路径,这个本地路径就是网络图片对应的本地临时路径,如何拿到本地临时路径,得借助小程序内置方法:wx.downloadFile
用法如下:我这里是下载的用户头像,这里的res.temFilePath就是本地临时路径了
注:下载图片的域名要在小程序后台的downloadFile里面加上才行
1 var that = this; 2 wx.downloadFile({ 3 url: that.data.userInfo.avatarUrl, 4 success: function (res) { 5 console.log('图片:' + res.tempFilePath); 6 that.setData({ 7 photoTempath: res.tempFilePath 8 }) 9 } 10 })
三、关于canvas自适应屏幕
我这里是需要自适应的,一开始我是想着能不能用%来写宽高,实践之后发现是不行的,于是在小程序api中找到wx.getSystemInfo方法拿到设备的宽高
var that = this; wx.getSystemInfo({ success: function (res) { console.log(res) that.setData({ width: res.windowWidth, height: res.windowHeight }) }
获取元素高度:
var that = this; const query = wx.createSelectorQuery(); query.select('.share-box').boundingClientRect(); query.exec(function (res) { that.setData({ footHeight: res[0].height }) console.log(that.data.footHeight) })
四、小程序码生成
前端调用后台接口获取小程序码,参数:page(小程序码的跳转页面),id(页面参数)
生成小程序码后同样需要获取本地临时路径才能在canvas中绘制出来,
注:通过小程序码进入的页面,在onload方法里面可以得到一个参数:scene,这个属性就是生成小程序码的时候传的那个页面参数
上述代码的实现效果如下:我这里的小程序码和banner图暂时没有,而且数据也是瞎写的,凑合看吧
canvas转成图片保存到相册
1 canvasToImage() { 2 var that = this; 3 // canvas画布转成图片 4 wx.canvasToTempFilePath({ 5 quality: 1, 6 fileType: 'jpg', 7 canvasId: 'shareBox', 8 success: function (res) { 9 wx.hideLoading(); 10 console.log('11' + res.tempFilePath); 11 that.setData({ 12 img_temp: res.tempFilePath 13 }) 14 // wx.previewImage({ 15 // current: res.tempFilePath, // 当前显示图片的http链接 16 // urls: [res.tempFilePath] // 需要预览的图片http链接列表 17 // }) 18 wx.saveImageToPhotosAlbum({ 19 filePath: res.tempFilePath, 20 success(res) { 21 console.log(res); 22 wx.showModal({ 23 title: '', 24 content: '图片已保存到相册,赶紧晒一下吧', 25 showCancel: false, 26 confirmText: '好的', 27 confirmColor: '#72B9C3', 28 success: function (res) { 29 if (res.confirm) { 30 console.log('用户点击确定'); 31 } 32 that.setData({ 33 visible: false 34 }) 35 } 36 }) 37 }, 38 fail: function (res) { 39 if (res.errMsg === "saveImageToPhotosAlbum:fail auth deny") { 40 wx.openSetting({ 41 success(settingdata) { 42 console.log(settingdata) 43 if (settingdata.authSetting['scope.writePhotosAlbum']) { 44 that.saveImg(); //保存失败尝试再次保存 45 } else { 46 console.log('获取权限失败,给出不给权限就无法正常使用的提示') 47 } 48 } 49 }) 50 } 51 } 52 }) 53 54 }, 55 fail: function (res) { 56 console.log(res) 57 } 58 }, this) 59 },
这样就可以把canvas转成图片保存在本地了,分享朋友圈在相册找图就好了