注冊登錄

小程序?qū)С雠笥讶笤敿?xì)記錄

2018-09-18
導(dǎo)讀:小程序提供了轉(zhuǎn)發(fā)給好友的接口,但是沒提供分享到朋友圈的接口。于是,只有引導(dǎo)用戶保存圖片分享到朋友圈。...

小程序提供了轉(zhuǎn)發(fā)給好友的接口,但是沒提供分享到朋友圈的接口。于是,只有引導(dǎo)用戶保存圖片分享到朋友圈。 兩種方案:用微信 api 手動保存,用 painter 。

微信 api

使用原生接口的話,大致是使用 canvas 繪制出海報,然后下載。所以重點(diǎn)是繪制出海報,下載的流程都是一樣的。當(dāng)然在保存圖片到相冊前,還會需要獲取保存圖片到相冊的權(quán)限??偨Y(jié)下來就是canvas繪制,獲取保存權(quán)限,保存圖片這三個步驟。 首先來看繪制海報,需要使用以下接口

  • wx.createCanvasContext 創(chuàng)建 canvas context
  • ctx.drawImage 繪制圖片到 canvas
  • ctx.fillText 寫文字
  • wx.getImageInfo 獲取網(wǎng)絡(luò)圖片的 tempFilePath
  • ctx.draw canvas 繪制

繪制的內(nèi)容很簡單,首先就是背景圖;然后是分享者的頭像;接下來是 @ xx 邀請你 這樣一個文本描述;最后就是底部的小程序碼。

首先,創(chuàng)建 canvas 畫布
<canvas canvas-id='canvas' class='canvas' :style="{height: windowHeight + 'px'}"/>
復(fù)制代碼

使用小程序 createCanvasContext api ,需要傳入 canvasid

const ctx = wx.createCanvasContext('canvas')
復(fù)制代碼

然后將背景圖片繪制出來,背景圖片是放在本地的圖片。

ctx.drawImage('../../../static/assets/img/poster_background.png', 0, 0, this.windowWidth, this.windowHeight)
復(fù)制代碼
然后寫上文字
ctx.setFontSize(12);
ctx.setFillStyle('#FFFFFF');
ctx.setTextAlign('center');
ctx.fillText(`${this.privateUserInfo.nickname} 邀您領(lǐng)取`, this.windowWidth / 2, this.transformScale(520))
復(fù)制代碼

這里會將原始尺寸和繪制的尺寸等比例轉(zhuǎn)換一下,就不贅述了。再接下來就是繪制小程序碼了。由于小程序碼是帶了分享者的信息,所以必須是臨時獲取的網(wǎng)絡(luò)圖片資源,具體怎么獲取帶有分享者信息的小程序碼,會專門寫一篇文章介紹。

繪制圖片

繪制頭像與小程序碼,這兩張圖片都是網(wǎng)絡(luò)資源,所以都要使用 wx. getImageInfo 接口將其下載下來放到微信內(nèi)存中,然后使用其response.path 繪制。小程序并不支持直接的繪制網(wǎng)絡(luò)圖片,而且也不支持 base64圖片的繪制(雖然模擬器上會有效果)。頭像的繪制還有有一個裁剪圓形頭像的過程。wx.getImageInfo是異步的,所以在回調(diào)函數(shù)里繪制,當(dāng)然這不是好的方式??梢允褂?promise 來解決,由于現(xiàn)在已經(jīng)不用這個代碼了,就沒有去改了。

wx.getImageInfo({
          src: miniProgramCodeSrc,
          success: (response) => {
            const miniProgramCodeSize = this.transformScale(160)
            ctx.drawImage(response.path, this.transformScale(85), this.transformScale(710), miniProgramCodeSize, miniProgramCodeSize)

            wx.getImageInfo({
              src: this.privateUserInfo.avatar,
              success: (response) => {
                const avatarSize = this.transformScale(100)
                //先繪制圓,裁剪成圓形圖片
                ctx.save();
                ctx.beginPath();
                //圓的原點(diǎn)x坐標(biāo),y坐標(biāo),半徑,起始弧度,終止弧度
                ctx.arc(this.transformScale(320), this.transformScale(425), avatarSize / 2, 0, 2 * Math.PI);
                ctx.setStrokeStyle('#ffffff');
                ctx.stroke();
                ctx.clip();

                ctx.drawImage(response.path, this.transformScale(270), this.transformScale(375), avatarSize, avatarSize)
                ctx.restore();

                ctx.draw(false, () => {
                  this.saveToTempFilePath()
                })
              }
            })
          }
        })
復(fù)制代碼

到這一步,繪制基本就結(jié)束了。我們所要的海報內(nèi)容已經(jīng)可以在 canvas 上呈現(xiàn)了,接下來就是將 canvas 的內(nèi)容保存為圖片了。值得提醒的是,ctx.draw這個接口也是異步的,需要在其回調(diào)中執(zhí)行下載的操作。

獲取 tempFilePath
  • wx.canvasToTempFilePath 獲取整個 canvas 的tempFilePath

保存圖片最重要的就是tempFilePath了,使用canvasToTempFilePath 獲取 tempFilePath。需要注意的是canvasToTempFilePath接口二參需要傳入 this。

saveToTempFilePath() {
        wx.canvasToTempFilePath({
          canvasId: 'canvas',
          success: (response) => {
            //獲取相冊授權(quán)
          }
        }, this)
      }
復(fù)制代碼

獲取 tempFilePath 成功后再獲取保存權(quán)限,當(dāng)然也可以先獲取保存權(quán)限,再獲取tempFilePath。

獲取保存權(quán)限

首先查看是否有保存權(quán)限,有權(quán)限就可以直接保存了。沒有權(quán)限就先獲取權(quán)限,再保存。

  • wx.getSetting 查看權(quán)限列表
  • wx.authorize 若沒有保存圖片權(quán)限,進(jìn)行授權(quán)
wx.getSetting({
  success: (res) => {
    if (!res.authSetting['scope.writePhotosAlbum']) {
      wx.authorize({
        scope:'scope.writePhotosAlbum',
        success: () => {
          this.saveImageToPhotosAlbumByWX(response.tempFilePath)
        }
      })
    } else {
      this.saveImageToPhotosAlbumByWX(response.tempFilePath)
    }
  }
})
復(fù)制代碼
保存圖片到相冊
  • wx.saveImageToPhotosAlbum 保存圖片到相冊

這一步就很簡單了,萬事俱備,只差保存了。調(diào)用 wx.saveImageToPhotosAlbum 即可。

saveImageToPhotosAlbumByWX(tempFilePath) {
        wx.saveImageToPhotosAlbum({
          filePath: tempFilePath,
          complete: () => {
            // 其他操作
          }
        })
      }
復(fù)制代碼

到這里,使用原生 api 保存一張分享朋友圈的海報就好了。

painter

painter 是什么呢?

小程序生成圖片庫,輕松通過 json 方式繪制一張可以發(fā)到朋友圈的圖片

painter 是酷家樂開源的小程序圖片生成庫,類似 echarts,使用配置對象渲染圖片到 canvas。渲染完成后回調(diào)會返回 tempFilePath,然后調(diào)用 wx.saveImageToPhotosAlbum 即可保存。保存的步驟和第一種方案一致,關(guān)鍵是獲取到 tempFilePath。

按照其 readme 來操作就好了,由于項目是使用了 mpvue,所以使用了 mpvue接入方案 。

使用 painter
<painter v-if="showPainter" class='canvas' @imgOK="onImgOk" :palette="palette"/>
復(fù)制代碼

為什么要使用 v-if 呢,需要在所有數(shù)據(jù)都準(zhǔn)備好了后再渲染 painter,否則會無限繪制。

data() {
  return {
    //painter 配置數(shù)據(jù)
    palette: {
      width: '640rpx',
      height: '1008rpx',
      background: '/static/assets/img/poster_background.png',
      views: [
        {
          type: 'image',
          url: '',
          css: {
            top: '380rpx',
            left: '320rpx',
            align: 'center',
            width: '100rpx',
            height: '100rpx',
            borderRadius: '50rpx'
          }
        }, {
          type: 'text',
          text: '',
          css: {
            top: '490rpx',
            left: '320rpx',
            align: 'center',
            fontSize: '24rpx',
            color: '#fff'
          }
        },
        {
          type: 'image',
          url: '',
          css: {
            top: '690rpx',
            left: '85rpx',
            width: '180rpx',
            height: '180rpx'
          }
        }
      ]
    }

  }
},

computed: {
  showPainter() {
    const avatar = this.palette.views[0].url
    const text = this.palette.views[1].text
    const qrCodeUrl = this.palette.views[2].url
    return avatar !== '' && text !== '' && qrCodeUrl!== ''
  }
}
復(fù)制代碼

在 painter繪制成功的回調(diào)里,將 tempFilePath 保存起來。接下來的權(quán)限獲取和保存圖片到相冊流程就和上一個方案一致了。但是,需要提醒的是,tempFilePath 需要放在全局變量中,不能放在data 中。

總結(jié)

總結(jié)一下,遇到的一些坑

  • 小程序canvas不能支持 base64
  • drow 有回調(diào)
  • drawImage 不能直接使用網(wǎng)絡(luò)圖片
  • 需要處理獲取權(quán)限,用戶拒絕后的場景
重磅推薦:小程序開店目錄

第一部分:小商店是什么

第二部分:如何開通一個小商店

第三部分:如何登錄小商店

第四部分:開店任務(wù)常見問題

第五部分:小商店可以賣什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結(jié)算

第十部分:小程序客服

第十一部分:電商創(chuàng)業(yè)

第十二部分:小程序游戲開發(fā)

電話咨詢 微信咨詢 預(yù)約演示 0元開店