效果图如下,用户每次点击分享图片的时候,从内容库中随机抽出一条数据,渲染在图片上,并且加上用户昵称和头像,用户可以保存到本地。
根据开发的顺序写一下吧,先要确定rpx单位,读取数据(昵称 头像、文字),再渲染圆角头像和本地的二维码图片,判断保存权限,关闭后再次点击再渲染。
目录
- 自适应rpx单位
- 读取用户昵称和头像
- 随机获取文字内容
- promisify.js的封装使用
- 渲染网络图片和本图片
- 圆角图片
- 保存权限
- 多次渲染清空
1. 自适应rpx单位
起初自己在?css ?里用的?px ?单位给?canvas ?设置的样式,在模拟器里切换机型后不能自适应,又换成?rpx ?单位。
canvas ?里渲染图片和文字也需要单位,需要把?px ?转成?rpx ?,?1rpx = 窗口宽度px/750 ?。
function createRpx2px() {
const { windowWidth } = wx.getSystemInfoSync()
return function(rpx) {
return windowWidth / 750 * rpx
}
}
const rpx2px = createRpx2px()
ctx.setFontSize(rpx2px(28))
ctx.fillText('长按左侧二维码',rpx2px(220),rpx2px(640))
复制代码
2. 读取用户昵称和头像
根据微信的api文档,需要使用?open-type="getUserInfo" ?属性的按钮获取用户授权,授权成功后调用?wx.getUserInfo ?方法获取用户详情。
<button class="button" open-type="getUserInfo" bindtap="share" >分享到朋友圈</button>
复制代码
封装获取用户详情的?Promise ?,并且返回昵称和图片地址。
3. 随机获取文字内容
云数据库可以使用类?mongo ?的?sample ?方法随机抽取数据,具体可见官方网文档。
size?为指定数量。
封装?Promise ?返回数据
getMsg(){
const db = wx.cloud.database()
return new Promise((resolve,reject) => {
db.collection('shareMsg').aggregate().sample({ size: 1 }).end().then(res=>{
resolve(res.list[0])
});
})
},复制代码
4. promisify.js的封装使用
Nodejs 8 有一个工具函数 util.promisify()。将一个接收回调函数参数的函数转换成一个返回Promise的函数。
js的编程中有很多需要异步的场景,刚才我们获取昵称和随机数据都用到了?Promise ?,这样写很麻烦,微信的api都遵循一样的规范,网上有封装好的代码,拿来主义。
promisify.js
const promisify = (api) => {
return (options,...params) => {
Object.assign({},options,{ success: resolve,fail: reject }),...params);
});
}
}
export default promisify
复制代码
使用示例
;
let userInfo = promisify(wx.getUserInfo);
userInfo().then(res => {
console.log(res)
})
复制代码
5. 渲染网络图片和本图片
读取网络图片要在公众平台设置合法域名。
接口返回的头像图片域名为?https://wx.qlogo.cn ,添加上就可以了。
渲染网络图片需要使用?wx.getImageInfo ?方法把网络图片变成本地图片再渲染,本地图片直接放入图片路径即可。
this.getInfo().then(userInfo => {
Promise.all([
wxGetImageInfo({
src: userInfo.avatarUrl
})
]).then(res => {
ctx = wx.createCanvasContext('shareCanvas')
ctx.drawImage(res[0].path,rpx2px(40),rpx2px(60),rpx2px(60));
ctx.drawImage('../../images/qrcode.jpeg',rpx2px(20),rpx2px(580),rpx2px(160),rpx2px(160));
})
})
复制代码
6. 圆角头像
ctx.save();
.beginPath();
.arc(rpx2px(70),rpx2px(90),51); font-weight: 700;">rpx2px(30),51); font-weight: 700;">Math.PI * 2,51); font-weight: 700;">false);
.clip();
.drawImage(res[0].path,51); font-weight: 700;">rpx2px(40),51); font-weight: 700;">rpx2px(60),51); font-weight: 700;">rpx2px(60));
.restore();
复制代码
7. 保存权限
第一步使用?wx.canvasToTempFilePath ?从?canvas ?导出图片,第二步使用?wx.saveImageToPhotosAlbum ?要把导出的图片的图片保存到相册。
保存到相册是需要用户授权的,用户授权拒绝后七天之内是不会在出现的授权框的,所以需要增加判断,如果无权限,显示设置按钮,跳转到权限设置页面。
,this).then(res => {
return wxSaveImageToPhotosAlbum({
filePath: res.tempFilePath
})
}).then(res => {
wx.showToast({
title: '已保存到相册'
})
}).catch(err => {
wx.showToast({
icon: 'none',title: '授权失败'
})
this.setData({setPage:true})
})
}
复制代码
<button hidden="{{!setPage}}" "openSetting" >设置权限</button>
复制代码
8. 多次渲染清空
对?canvas ?不是特别熟悉,从翻api说画一个图形,然后在清除图片范围内的内容。
ctx?对象要多次操作,需要提取为全局变量,另外创建时要保证DOM渲染完毕。
let ctx = wx.createCanvasContext('shareCanvas')
复制代码
不过在模拟器中多次渲染会出现空白的情况,但是手机实测是正常的。
好了,这个是在?【小程序 + 云开发】体重记录小程序 上手笔记?发表后继续新增的功能,下次希望云函数新增定时任务和推送的内容。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|