在做微信小程序的时候,很多都会用到生成海报分享功能,刚好最近项目有这个需求,今天就发出来记录下
首先是使用canvas绘制一张海报,微信小程序的canvas有老版本和新版本我是用的是新版本
代码如下
<canvas class="canvas" type="2d" id="myCanvas"></canvas>
js部分
我的做法是给canvas隐藏了不看到 ,等canvas绘制完毕后导出的url直接赋给image的url,然后弹出层展示,只展示生成的海报和保存图片按钮
qrcode(e) {
let _this = this
let type = e.currentTarget.dataset.type
if (_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].node
const ctx = canvas.getContext('2d')
// 获取设备像素比
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
// 商品图片
const bg = canvas.createImage();
bg.src = _this.data.goodList.imgurl
bg.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.data
code.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官方文档都有,只是做的时候需要一个一个查
附上效果图
文章来源地址https://www.toymoban.com/news/detail-404696.html
发帖只是记录,谢谢观看文章来源:https://www.toymoban.com/news/detail-404696.html
到了这里,关于微信小程序使用canvas绘制海报并保存本地相册的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!