Canvas API of applets does not support applets’ unique RPX adaptive size unit like other applets. The unit used to draw content is still PX. So how to achieve adaptive screen of different sizes?

Our common reference screen size in development (iPhone6) is: 375*667;

So if you want to adapt to other screen sizes, just scale the drawing size of iPhone6 to convert:

Gets the system screen size

Use the wx.getsysteminfo API to get the screen width, then divide the width of the iPhone6 screen into relative units

// called in onLoad
const that = this
wx.getSystemInfo({
  success: function (res) {
    console.log(res)
    that.setData({
      model: res.model,
      screen_width: res.windowWidth/375.screen_height: res.windowHeight
    })
  }
})
Copy the code

In the drawing method, the parameter is multiplied by relative units to achieve adaptive

RPX is the relative unit of different screen widths. The measured width is the actual measured PX pixel value * RPX. After iPhone5, iPhone6, iPhone7… Can be adaptive.

The HTML here also dynamically sets the width and height

<canvas  canvas-id="PosterCanvas" style="width:{{screen_width*375+'px'}}; Height: {{screen_height * 1.21 + 'px'}}"></canvas>
Copy the code
drawPoster(){
    let ctx = wx.createCanvasContext('PosterCanvas'),that=this.data;
    console.log('Phone Model' + that.model,'wide'+that.screen_width*375.'high'+ that.screen_height)
    let rpx = that.screen_width
    // The actual width of the screen is measured in pixels * RPX. After iPhone5, iPhone6, iPhone7... Can be adaptive.
    ctx.setFillStyle('#1A1A1A')
    ctx.fillRect(0.0, rpx * 375, that.screen_height * 1.21)
    ctx.fillStyle = "#E8CDAA";
    ctx.setFontSize(29*rpx)
    ctx.font = 'normal 400 Source Han Sans CN';
    ctx.fillText('Hi friends'.133*rpx,66*rpx)
    ctx.fillText('Get gifts before you buy a car'.84*rpx, 119*rpx)
    ctx.drawImage('.. /.. /img/sell_index5.png'.26*rpx, 185*rpx, 324*rpx, 314*rpx)
    ctx.drawImage('.. /.. /img/post_car2x.png'.66 * rpx, 222 * rpx, 243 * rpx, 145 * rpx)
    ctx.setFontSize(16*rpx)
    ctx.font = 'normal 400 Source Han Sans CN';
    ctx.fillText('Long press scan for more offers'.108*rpx, 545*rpx)
    ctx.drawImage('.. /.. /img/code_icon2x.png'.68 * rpx, 575 * rpx, 79 * rpx, 79 * rpx)
    ctx.drawImage('.. /.. /img/code2_icon2x.png'.229 * rpx, 575 * rpx, 79 * rpx, 79 * rpx)
    ctx.setStrokeStyle('# 666666')
    ctx.setLineWidth(1*rpx)
    ctx.lineTo(187*rpx,602*rpx)
    ctx.lineTo(187*rpx, 630*rpx)
    ctx.stroke()
    ctx.fillStyle = "#fff"
    ctx.setFontSize(13 * rpx)
    ctx.fillText('XXX Technology Automobile Sales Company'.119 * rpx, 663 * rpx)
    ctx.fillStyle = "# 666666"
    ctx.fillText('Wangjing XXX Technology Building, Chaoyang District'.109 * rpx, 689 * rpx)
    ctx.setFillStyle('#fff')
    ctx.draw()
  },
Copy the code

If the picture is an online addressctx.drawImage()Can’t draw a picture because it calls a GET request, it’s an asynchronous operation, and it doesn’t wait for the GET to returntx.draw()Paint the canvas. The solution lies inwx.downloadFile()Successfully downloaded the picture before drawing the canvas.

wx.downloadFile({
      url: that.data.url,
      success(res) {
        if (res.statusCode === 200) {
          / / activity
          ctx.drawImage(res.tempFilePath, 66 * rpx, 222 * rpx, 243 * rpx, 145 * rpx)
          / / qr code
          ctx.draw()
        }
      }
    })
Copy the code

Save to album

It’s as simple as calling canvasToTempFilePath() in the draw callback after drawing an image to create a zero-hour link in memory and saveImageToPhotosAlbum(). There’s authorization involved. If you refuse authorization the first time, it won’t remind you of authorization on your iPhone the second time, so you have to call it manually; The following attached code!

ctx.draw(true, () = > {// console.log(' done ')
        wx.canvasToTempFilePath()({
          x: 0.y: 0.width: rpx * 375.height: that.screen_height * 1.21.canvasId: 'PosterCanvas'.success: function (res) {
            // console.log(res.tempFilePath);
            wx.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success: (res) = > {
                console.log(res)
              },
              fail: (err) = >{}})}})Copy the code

The code to remind authorization again after authorization is denied

mpvue.saveImageToPhotosAlbum({
        filePath: __path,
        success(res) {
          mpvue.showToast({
          title: 'Saved successfully'.icon: 'success'.duration: 800.mask:true
          });
         },
        fail(res) {
            if (res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny" || res.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {

          mpvue.showModal({
                title: 'tip'.content: 'Need your authorization to save album'.showCancel: false.success:modalSuccess= >{
                  mpvue.openSetting({
                    success(settingdata) {
                      // console.log("settingdata", settingdata)
                      if (settingdata.authSetting['scope.writePhotosAlbum']) {
                        mpvue.showModal({
                          title: 'tip'.content: 'Permission obtained successfully, click the image again to save'.showCancel: false})},else {
                        mpvue.showModal({
                          title: 'tip'.content: 'Failed to obtain permission, will not save to album oh ~'.showCancel: false,
                        })
                      }
                    },
                    fail(failData) {
                      console.log("failData",failData)
                    },
                    complete(finishData) {
                      console.log("finishData", finishData)
                    }
                  })
                }
              })
          }
         }
      });

Copy the code

So far calculate finished, can help you to give a thumbs-up!