专业编程基础技术教程

网站首页 > 基础教程 正文

小程序 随机读取数据并生成分享图片 上手笔记

ccvgpt 2024-10-29 13:21:27 基础教程 12 ℃

效果图如下,用户每次点击分享图片的时候,从内容库中随机抽出一条数据,渲染在图片上,并且加上用户昵称和头像,用户可以保存到本地。

功能不难,但是有一些小细节,还是列出来记录下吧。

小程序 随机读取数据并生成分享图片 上手笔记

根据开发的顺序写一下吧,先要确定rpx单位,读取数据(昵称 头像、文字),再渲染圆角头像和本地的二维码图片,判断保存权限,关闭后再次点击再渲染。

目录

  1. 自适应rpx单位
  2. 读取用户昵称和头像
  3. 随机获取文字内容
  4. promisify.js的封装使用
  5. 渲染网络图片和本图片
  6. 圆角图片
  7. 保存权限
  8. 多次渲染清空

1. 自适应rpx单位

起初自己在css里用的px单位给canvas设置的样式,在模拟器里切换机型后不能自适应,又换成rpx单位。

canvas里渲染图片和文字也需要单位,需要把px转成rpx,1rpx = 窗口宽度px/750。

<!--rpx2px函数-->
function createRpx2px() {
 const { windowWidth } = wx.getSystemInfoSync()
 return function(rpx) {
 return windowWidth / 750 * rpx
 }
}
<!--使用rpx2px-->
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,并且返回昵称和图片地址。

<!--获取用户详情-->
getInfo(){
 return new Promise((resolve, reject) => {
 wx.getUserInfo({
 success: function(res) {
 let { nickName , avatarUrl } = res.userInfo
 resolve({ nickName , avatarUrl })
 }
 })
 })
 }
复制代码

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) => {
 return new Promise((resolve, reject) => {
 api(Object.assign({}, options, { success: resolve, fail: reject }), ...params);
 });
 }
}
export default promisify
复制代码

使用示例

import promisify from '../../lib/promisify.js'; 
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), rpx2px(60)); 
 
 <!--本地图片-->
 ctx.drawImage('../../images/qrcode.jpeg', rpx2px(20), rpx2px(580), rpx2px(160),rpx2px(160));
 })
})
复制代码

6. 圆角头像

ctx.save(); 
ctx.beginPath(); 
ctx.arc(rpx2px(70), rpx2px(90), rpx2px(30), 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(res[0].path, rpx2px(40), rpx2px(60), rpx2px(60), rpx2px(60)); 
ctx.restore(); 
复制代码

7. 保存权限

第一步使用wx.canvasToTempFilePath从canvas导出图片,第二步使用wx.saveImageToPhotosAlbum要把导出的图片的图片保存到相册。

保存到相册是需要用户授权的,用户授权拒绝后七天之内是不会在出现的授权框的,所以需要增加判断,如果无权限,显示设置按钮,跳转到权限设置页面。

<!--保存按钮-->
saveImg(){
 const wxCanvasToTempFilePath = promisify(wx.canvasToTempFilePath)
 const wxSaveImageToPhotosAlbum = promisify(wx.saveImageToPhotosAlbum)
 wxCanvasToTempFilePath({
 canvasId: 'shareCanvas'
 }, 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}}" open-type="openSetting" >设置权限</button>
复制代码

8. 多次渲染清空

对canvas不是特别熟悉,从翻api说画一个图形,然后在清除图片范围内的内容。

ctx.fillRect(0,0,rpx2px(500),rpx2px(760))
ctx.clearRect(0,0,rpx2px(500),rpx2px(760))
ctx.draw()
复制代码

ctx对象要多次操作,需要提取为全局变量,另外创建时要保证DOM渲染完毕。

let ctx = wx.createCanvasContext('shareCanvas')
复制代码

不过在模拟器中多次渲染会出现空白的情况,但是手机实测是正常的。

最近发表
标签列表