100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 微信小程序 —— canvas生成海报图与分享

微信小程序 —— canvas生成海报图与分享

时间:2022-03-24 03:36:34

相关推荐

微信小程序 —— canvas生成海报图与分享

整体思路

获取手机屏幕大小去依据设计尺寸比例调整 —wx.getSystemInfo网络图片、base64图片保存到到本地临时文件路径canvas绘制图片 —wx.createCanvasContext获取用户相册权限 —wx.getSettingcanvas海报保存到本地临时文件路径 —canvasToTempFilePathcanvas图片保存到本地相册 —saveImageToPhotosAlbum

效果图

代码示例

wxml

<block wx:if="{{canvasType}}"><canvas class="canvas" canvas-id="shareCanvas" bindtouchstart="start" bindtouchmove="move" bindtouchend="end"></canvas></block><view bindtap="shareBtn">保存分享图片</view>

js

// 点击保存图片按钮shareBtn() {setTimeout(() => {this.getSysInfo()}, 200)},

//获取图片信息和屏幕尺寸getSysInfo() {let that = thislet bgImgUrl = this._mapHttpToHttps(that.data.canvasInfoData.posterUrl)let iconUrl = this._mapHttpToHttps(that.data.canvasInfoData.avatar)wx.getSystemInfo({success(res) {that.setData({canvasWidth: res.windowWidth,canvasHeight: res.windowHeight})that.getImginfo([bgImgUrl, iconUrl], 0);}})},

// 获取图片信息getImginfo(urlArr, _type) {let that = this;wx.getImageInfo({src: urlArr[_type], //服务器返回的带参数的小程序码地址success: function (res) {//res.path是网络图片的本地地址if (_type === 0) {//背景图片that.setData({bgImgUrl: res.path,})that.getImginfo(urlArr, 1)} else {//头像图片that.setData({iconUrl: res.path,loadType: true,iconWidth: res.width,iconHeight: res.height,})// 创建canvas图片that.canvasImg();}},fail: function (res) {//失败回调console.log('错误-res', _type, res)}});},

// 将http转为https_mapHttpToHttps(rawUrl) {if (rawUrl.indexOf(":") < 0) {return rawUrl}const urlCompnent = rawUrl.split(":")if (urlCompnent.length === 2) {if (urlCompnent[0] === 'http') {urlCompnent[0] = 'https'return `${urlCompnent[0]}:${urlCompnent[1]}`}}return rawUrl},

生成图片 绘制canvas

canvasImg() {let that = this;wx.showLoading({title: '图片正在生成'});var x = this.data.canvasWidth / 750; //设置相对canvas自适应根元素大小const ctx = wx.createCanvasContext('shareCanvas', this);ctx.drawImage(this.data.bgImgUrl, 0, 0, 750 * x, 1334 * x);//方形二维码框ctx.save();ctx.fillStyle = "#fff";ctx.fillRect(560 * x, 1144 * x, 160 * x, 160 * x);ctx.drawImage(this.data.base64Url, 570 * x, 1155 * x, 140 * x, 140 * x);ctx.restore();//圆形头像框//圆形头像框ctx.save();ctx.beginPath();ctx.arc(150 * x, 800 * x, 90 * x, 0, 2 * Math.PI);ctx.clip();ctx.fillStyle = "#fff";//头像 // ctx.drawImage(this.data.iconUrl, 60 * x, 710 * x, 180 * x, 180 * x);//图片长宽let h = this.data.iconHeightlet w = this.data.iconWidth//宽高比let dw = 180 / this.data.iconWidthlet dh = 180 / this.data.iconHeight// 裁剪图片中间部分if (w > 180 && h > 180 || w < 180 && h < 180) {if (dw > dh) {ctx.drawImage(this.data.iconUrl, 0, (h - 180 / dw) / 2, w, 180 / dw, 60 * x, 710 * x, 180 * x, 180 * x)} else {ctx.drawImage(this.data.iconUrl, (w - 180 / dh) / 2, 0, 180 / dh, h, 60 * x, 710 * x, 180 * x, 180 * x)}}// 拉伸图片else {if (w < 180) {ctx.drawImage(this.data.iconUrl, 0, (h - 180 / dw) / 2, w, 180 / dw, 60 * x, 710 * x, 180 * x, 180 * x)} else {ctx.drawImage(this.data.iconUrl, (w - 180 / dh) / 2, 0, 180 / dh, h, 60 * x, 710 * x, 180 * x, 180 * x)}}ctx.restore();ctx.beginPath()ctx.moveTo(0, 1010 * x);ctx.lineTo(750 * x, 1010 * x);ctx.strokeStyle = "#F0F5F8";ctx.stroke();ctx.closePath();//名字ctx.save();ctx.fillStyle = '#3C3C3C';ctx.font = 'normal bold 17px sans-serif';ctx.fillText(`${this.data.canvasInfoData.name}`, 272 * x, 790 * x);ctx.restore();//等等XXXXXXXXXXXXXXXXXXXctx.save()let textLength = ctx.measureText(this.data.currentTask).width// 长度按照文字长度计算 218 * xlet rectX = (708 * x) - textLength - 5 //476 * xthat.draw(ctx, rectX, 848 * x, textLength + 10, 43 * x, 5, '#fff', '#008CD6')ctx.restore();// 参与人数ctx.save()that.draw(ctx, 20 * x, 40 * x, 240 * x, 55 * x, 15, 'rgba(0, 0, 0, 0.3)', 'rgba(0, 0, 0, 0)');ctx.fillStyle = '#fff'; // 文字颜色ctx.setTextAlign('center');ctx.font = 'normal 400 13px sans-serif';ctx.fillText(`超过${this.data.canvasInfoData.participantsCount}人参与`, 140 * x, 76 * x);ctx.restore();ctx.draw();that.setData({canvasType: true});setTimeout(() => {this.savePoster()}, 300)wx.hideLoading();},

保存海报到相册

// 授权 getSetting检测用户有没有开启相册权限 有的话直接保存 没有的话弹到权限页面让用户授权savePoster() {let that = this;wx.showLoading({title: '正在保存',mask: true,});wx.getSetting({success(res) {if (res.authSetting['scope.writePhotosAlbum']) {that.saveImg()} else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {wx.authorize({scope: 'scope.writePhotosAlbum',success() {that.saveImg()},fail() {wx.hideLoading();that.authConfirm()}})} else {wx.hideLoading();that.authConfirm()}}})},

// 授权拒绝后,再次授权提示弹窗authConfirm() {let that = thiswx.showModal({content: '检测到您没打开保存图片权限,是否去设置打开?',confirmText: "确认",cancelText: "取消",success: function (res) {if (res.confirm) {wx.openSetting({success(res) {if (res.authSetting['scope.writePhotosAlbum']) {that.saveImg();} else {wx.showToast({title: '您没有授权,无法保存到相册',icon: 'none'})}}})} else {wx.showToast({title: '您没有授权,无法保存到相册',icon: 'none'})}}});},

// 图片保存到本地saveImg() {wx.canvasToTempFilePath({canvasId: 'shareCanvas',quality: 1,success: function (res) {wx.hideLoading();var tempFilePath = res.tempFilePath;wx.saveImageToPhotosAlbum({filePath: tempFilePath,success(res) {wx.showModal({content: '海报保存成功,你可以从手机相册中把海报分享到朋友圈',showCancel: false,confirmText: '好的',confirmColor: '#333',})},fail: function (res) {wx.showToast({title: '保存失败',icon: 'none',duration: 2000});}})}}, this);}

问题总结

生成的头像显示不全

找到一篇文章解决了这个问题 感谢 canvas实现图片拉伸、压缩与裁剪文字的描绘位置 textBaseline 的介绍绘制圆角矩形 传送带canvas的drawImage方法只支持本地图片,不支持网络图片 base64保存本地地址绘制顺序影响显示,合理使用save()restore()在page页面中,this是默认的,但是在自定义组件中则需要指定this

保存图片的时候必须打开调试才能保存,不打开就保存不了是因为需要配置https的域名

后端返回的如果是域名下的http图片就需要去处理变成https

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