2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 微信小程序使用canvas绘制海报并保存本地相册

微信小程序使用canvas绘制海报并保存本地相册

时间:2024-01-08 09:21:33

相关推荐

微信小程序使用canvas绘制海报并保存本地相册

在做微信小程序的时候,很多都会用到生成海报分享功能,刚好最近项目有这个需求,今天就发出来记录下

首先是使用canvas绘制一张海报,微信小程序的canvas有老版本和新版本我是用的是新版本

代码如下

<canvas class="canvas" type="2d" id="myCanvas"></canvas>

js部分

我的做法是给canvas隐藏了不看到 ,等canvas绘制完毕后导出的url直接赋给image的url,然后弹出层展示,只展示生成的海报和保存图片按钮

qrcode(e) {let _this = thislet type = e.currentTarget.dataset.typeif (_this.data.canvasurl !== '' && type === 'open') {_this.setData({show: true})return}if (type === 'open') {wx.showLoading({title: '分享海报生成中',})const query = wx.createSelectorQuery()query.select('#myCanvas').fields({node: true,size: true}).exec((res) => {const canvas = res[0].nodeconst ctx = canvas.getContext('2d')// 获取设备像素比const dpr = wx.getSystemInfoSync().pixelRatio;canvas.width = res[0].width * dprcanvas.height = res[0].height * dprctx.scale(dpr, dpr)// 商品图片const bg = canvas.createImage();bg.src = _this.data.goodList.imgurlbg.onload = () => {ctx.drawImage(bg, 0, 0, 251, 225)}// 分割线ctx.strokeStyle = 'rgba(255,255,255,0.1)';ctx.beginPath();ctx.moveTo(0, 225);ctx.lineTo(251, 225);ctx.stroke();// 下半部分矩形ctx.fillStyle = '#fff';ctx.fillRect(0, 0, 251, 406);ctx.fill()// 商品名称ctx.fillStyle = '#000';ctx.font = "16px Arial";ctx.fillText(_this.data.goodList.goods_name, 12.5, 250);ctx.fill()// 商品规格let width = _this.data.goodList.goods_attr.length * 10_this.strokeRoundRect(ctx, 12.5, 260, width, 20, 10, 'rgba(255, 111, 96,0.2)')ctx.font = "12px Arial";ctx.fillStyle = "#FF6F60";ctx.fillText(_this.data.goodList.goods_attr, 20, 274);// 商品价格ctx.font = "20px Arial";ctx.fillText('¥' + _this.data.goodList.goods_price, 150, 280);// 最下方文字ctx.font = "12px Arial";ctx.fillStyle = "#949494";ctx.fillText('长按识别·去看看', 77, 380);// 绘制二维码App._post_form('qr', {id: _this.data.goodList.goods_id}, result => {const code = canvas.createImage();code.src = result.datacode.onload = () => {ctx.drawImage(code, 80, 285, 80, 80)}setTimeout(() => {_this.setData({// 导出canvas的url(base64格式)canvasurl: canvas.toDataURL('image/png'),show: true})wx.hideLoading()}, 1000)})})} else {_this.setData({show: false})}},

canvas绘制完毕,导出url后开始实现保存本地功能

如果是后端返的海报图片的话直接使用wx.downloadFile方法先下载到本地然后使用

wx.saveImageToPhotosAlbum再保存到相册

我是用的是canvas绘制后生成的base64所以先将base64转成图片保存在本地再使用wx.saveImageToPhotosAlbum保存到相册

// 保存图片到本地download() {const _this = this;// 生成临时路径var filepath = wx.env.USER_DATA_PATH + '/test.png';//获取文件管理器对象var aa = wx.getFileSystemManager();aa.writeFile({filePath: filepath,//只保留base64编码 截掉data:image/png;base64,data: _this.data.canvasurl.slice(22),encoding: 'base64',success: function (res) {wx.showLoading({title: '保存中...'})wx.saveImageToPhotosAlbum({filePath: filepath,success: function (data) {console.log('保存成功', data)wx.hideLoading()_this.setData({show: false})wx.showToast({title: '保存成功',icon: 'success',duration: 2000})// 删除下载暂存在本地的图片let fileMgr = wx.getFileSystemManager()fileMgr.unlink({filePath: res.filePath,success: () => {console.log('删除缓存成功!')}})},fail: function (err) {// 判断用户是否授权相册写入权限if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail:auth denied") {//当初用户拒绝,再次发起授权wx.showModal({title: '提示',content: '需要您授权保存相册',showCancel: false,success: () => {wx.openSetting({success(settingdata) {if (settingdata.authSetting['scope.writePhotosAlbum']) {wx.showModal({title: '提示',content: '获取权限成功,再次点击按钮即可保存',showCancel: false,})} else {wx.showModal({title: '提示',content: '获取权限失败,将无法保存到相册',showCancel: false,})}},fail(failData) {console.log("failData", failData)},complete(finishData) {console.log("finishData", finishData)}})}})}},complete(result) {//console.log(result);//wx.hideLoading()}})}})},

所有代码对应的注释都在里面,所有的API官方文档都有,只是做的时候需要一个一个查

附上效果图

发帖只是记录,谢谢观看

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