[開蓋即食]小程式Canvas官方新版API實戰

前端智酷方程發表於2020-04-03

image

官方文件
最近本人在開發一個新專案的時候,注意到官方在2.9.0開始支援了一個canvas 2D的新API,同時對webGL上支援也有了很大的改進,相信很多人用canvas的元件做一些分享海報,戰績和新聞帖功能。

新寫法

這裡是新的引入方式。 官方文件地址: developers.weixin.qq.com/miniprogram…

那麼新的canvas2D API有啥好處呢?

  • 原本的API微信有做一定的修改,現在全面支援源生H5 JS的寫法,遷移H5的老程式碼變成更加容易,學習成本更低
  • 修復了一些詭異的BUG,例如原本在IOS早期版本寫法順序會導致clip()圖片裁切失效等~
  • 效能上的優化和提升,複雜動畫上幀數明顯

舉例寫法上的一些改變:

1、設定font的寫法:

//原本(傳值的寫法)
ctx.setFontSize(20);
ctx.fillText('MINA', 100, 100)
ctx.draw()

//現在(和源生H5寫法一致,賦值)
ctx.font = "16px";
ctx.fillStyle = 'blue'; //可以直接寫顏色,原本的不支援
//不需要 ctx.draw()
複製程式碼

2、獲取並新增圖片寫法:

//原本
//使用的是 wx.getImageInfo的方法
wx.getImageInfo({
    src: mainImg,//伺服器返回的圖片地址
    success: function (res) {
        console.log(res);
        ctx.drawImage(res.path, 0, 0);
        ctx.draw(true);
    },
    fail: function (res) {
        //失敗回撥
    }
});

//現在
//可以直接img.onload呼叫
const headerImg = canvas.createImage();
headerImg.src = headImage;//微信請求返回頭像
headerImg.onload = () => {
    ctx.save();
    ctx.beginPath()//開始建立一個路徑
    ctx.arc(38, 288, 18, 0, 2 * Math.PI, false)//畫一個圓形裁剪區域
    ctx.clip()//裁剪
    ctx.drawImage(headerImg,0,0);
    ctx.closePath();
    ctx.restore();
}
複製程式碼

3、將canvas生成虛擬地址便於下載(重點):

canvasApi
由於官方文件沒有寫清楚,誤導了挺多人的。這裡canvas物件必須通過選擇器獲取,並獲得對應的node節點。

async saveImg() {
    let self = this;
    //這裡是重點  新版本的type 2d 獲取方法
    const query = wx.createSelectorQuery();
    const canvasObj = await new Promise((resolve, reject) => {
      query.select('#posterCanvas')
        .fields({ node: true, size: true })
        .exec(async (res) => {
          resolve(res[0].node);
        })
    });
    console.log(canvasObj);
    wx.canvasToTempFilePath({
      //fileType: 'jpg',
      //canvasId: 'posterCanvas', //之前的寫法
      canvas: canvasObj, //現在的寫法
      success: (res) => {
        console.log(res);
        self.setData({ canClose: true });
        //儲存圖片
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function (data) {
            wx.showToast({
              title: '已儲存到相簿',
              icon: 'success',
              duration: 2000
            })
            // setTimeout(() => {
            //   self.setData({show: false})
            // }, 6000);
          },
          fail: function (err) {
            console.log(err);
            if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
              console.log("當初使用者拒絕,再次發起授權")
            } else {
              util.showToast("請截圖儲存分享");
            }
          },
          complete(res) {
            wx.hideLoading();
            console.log(res);
          }
        })
      },
      fail(res) {
        console.log(res);
      }
    }, this)
  },
複製程式碼

分享個canvas海報的程式碼片段:

canvas生成海報demo

片段名: PoCf4emw7TgE

片段link: developers.weixin.qq.com/s/PoCf4emw7…

如何匯入
儲存結果

一些奇怪的問題(注意!!!)

  1. canvas 2d 目前(2020年4月3日)還不支援真機除錯,會報錯!!!
  2. IDE工具 1.02.2003190 直接儲存新版本canvas的API圖片是打不開的,但是直接用手機儲存在相簿是沒問題的,請更新到1.02.2003250 最新版即可解決~
  3. 一些老款手機用新的API儲存圖片會有報錯問題,如華為NOTE10,請更新系統到能支援的最新,且微信也是,即可解決~
  4. 部分Android裝置詭異的閃退和報錯
    image
    這種有可能是程式碼寫法的問題,比如:
//預設寫法  會導致部分Android機器 閃退
ctx.font = "bold 16px";
ctx.fillStyle = "#000"

//在canvas 2D的寫法中,所以寫法必須規範且完整
ctx.font = "normal bold 12px sans-serif";  
ctx.fillStyle = '#707070'; 
複製程式碼

所以在canvas 2D 的環境,所以寫法必須原始且規範,不能用預設寫法,不然就會有詭異的閃退/報錯。

總結,相對之前還要看官方文件的canvas自定義API,現在寫起來更加的方便,老程式碼遷移起來得心應手,只要你之前會canvas,那麼各種效果和動畫,拿來就懟,沒什麼大問題~

總結,web-view還是非常實用的元件,但儘量避免越牆的騷操作,且用且珍惜~

往期回顧:

[開蓋即食]小程式Canvas官方新版API實戰

相關文章