用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 教程 查看内容

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

Rolan 2019-7-29 00:25

效果图如下,用户每次点击分享图片的时候,从内容库中随机抽出一条数据,渲染在图片上,并且加上用户昵称和头像,用户可以保存到本地。功能不难,但是有一些小细节,还是列出来记录下吧。根据开发的顺序写一下吧,先 ...

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


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

根据开发的顺序写一下吧,先要确定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')
复制代码

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

好了,这个是在 【小程序 + 云开发】体重记录小程序 上手笔记 发表后继续新增的功能,下次希望云函数新增定时任务和推送的内容。

鲜花
鲜花
鸡蛋
鸡蛋
分享至 : QQ空间
收藏
原作者: 愚坤 来自: 掘金