The effect picture is as follows. Every time the user clicks to share an image, he randomly selects a piece of data from the content library and renders it on the image, adding the user’s nickname and avatar, and the user can save it locally.

It’s not that hard to do, but there are a few little details, so let’s write them down.

Write it according to the order of development, first to determine the RPX unit, read the data (nickname head, text), and then render rounded head and local TWO-DIMENSIONAL code picture, determine the permission to save, close and click again after rendering.

directory

  1. Adaptive RPX units
  2. Read the user’s nickname and profile picture
  3. Get text content randomly
  4. Promisify. Js package use
  5. Render the web image and this image
  6. The rounded picture
  7. Save the permissions
  8. Multiple render empties

1. Adaptive RPX units

At first, I used the PX unit in CSS to set the canvas style, but I couldn’t adapt to it after switching models in the simulator, so I changed to RPX unit.

Canvas rendering image and text also needs units. Convert PX to RPX, 1rpx = window width px/750.

<! - rpx2px function -- -- >function createRpx2px() {
  const { windowWidth } = wx.getSystemInfoSync()
  return function(rpx) {
    return windowWidth / 750* rpx } } <! - use rpx2px -- -- >const rpx2px = createRpx2px()
ctx.setFontSize(rpx2px(28))
ctx.fillText('Long press the left qr code', rpx2px(220), rpx2px(640))
Copy the code

2. Read the user’s nickname and profile picture

According to the API document of wechat, the button of open-type=”getUserInfo” attribute should be used to obtain user authorization, and the wx.getUserInfo method should be used to obtain user details after the authorization is successful.

<button class="button" open-type="getUserInfo" bindtap="share" >Share it on moments</button>
Copy the code

Encapsulate a Promise that gets the user’s details and returns the nickname and image address.

<! Get user details --> getInfo(){return new Promise((resolve, reject) = > {
      wx.getUserInfo({
        success: function(res) {
          let { nickName , avatarUrl } = res.userInfo
          resolve({ nickName , avatarUrl })
        }
      })
    })
  }
Copy the code

3. Random text retrieval

Cloud database can use sample method like Mongo to randomly extract data, the details can be seen in the official website documents.

Size indicates the specified number.

Encapsulate the Promise return data

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])}); })},Copy the code

4. Encapsulation and use of promisify

Nodejs 8 has a utility function util.promisify(). Convert a function that takes a callback function argument to a function that returns a Promise.

There are many asynchronous scenarios in JS programming. Just now, we used Promise to obtain nicknames and random data, which is very troublesome to write. Wechat apis all follow the same specifications, and there are encapsulated codes on the Internet.

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
Copy the code

Use the sample

import promisify from '.. /.. /lib/promisify.js'; 

let userInfo = promisify(wx.getUserInfo);
userInfo().then(res= > {
  console.log(res)
})
Copy the code

5. Render the network image and this image

Read network pictures to set up a legitimate domain name in the public platform.

https://wx.qlogo.cn

To render a network image, use the wx.getImageInfo method to turn the network image into a local image, and then render the local image directly into the image path.

 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)); 
    
        <! -- Local image -->ctx.drawImage('.. /.. /images/qrcode.jpeg', rpx2px(20), rpx2px(580), rpx2px(160),rpx2px(160)); })})Copy the code

6. Rounded heads

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(); 
Copy the code

7. Save the permission

. The first step in using wx canvasToTempFilePath derived from canvas pictures, the second step is to use wx. SaveImageToPhotosAlbum to export the pictures saved to the photo album.

The user’s authorization is required to save to the album, and the authorization box will not appear within seven days after the user’s authorization rejection. Therefore, it is necessary to add judgment. If the user has no permission, the setting button will be displayed to jump to the permission setting page.

<! -- save button --> 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: 'Saved to album'
        })
    }).catch(err= > {
      wx.showToast({
          icon: 'none'.title: 'Authorization failed'}) <! -- Display authorization button -->this.setData({setPage:true})})}Copy the code
<button hidden="{{! setPage}}" open-type="openSetting" >Set the permissions</button>
Copy the code

8. Multiple render empties

I am not very familiar with canvas. According to the translation API, draw a graph and then clear the content within the scope of the picture.

ctx.fillRect(0.0,rpx2px(500),rpx2px(760))
ctx.clearRect(0.0,rpx2px(500),rpx2px(760))
ctx.draw()
Copy the code

CTX objects need to be manipulated multiple times, extracted as global variables, and created with the DOM rendered.

let ctx = wx.createCanvasContext('shareCanvas')
Copy the code

However, several times in the simulator rendering will appear blank, but the mobile phone test is normal.

Well, this is in [small program + cloud development] weight record small program after the release of notes to continue to add new functions, next time I hope the cloud function to add scheduled tasks and push content.

Warehouse address: github.com/nihaojob/21…

Encourage themselves: paper come zhongjue shallow, must know this to practice, refueling.