關於在小程序中生成自定義分享轉發圖的開發(即用canvas生成需求所要的圖片在轉發的時候作為轉發圖)


前言:這陣子接手小程序的開發,也算是遇到一些問題,學習過程中也做一些自己的總結。主要的一個需求就是在用戶進行轉發的時候轉發圖片都不一樣,而且其中數據是要隨着更改的。第一思路用到的就是canvas,查了一些相關資料,參照思路,最后也是實現了產品所要的功能。其他也不多說,在下面直接上一些實現思路和代碼吧。PS:因為我用的Taro框架,是react寫法,標簽就不換了,看官們能看懂的,就是原生小程序標簽變大小寫

(這里是實現分享轉發的時候每次生成不一樣的分享圖片)

HTML部分(CSS就不放上來了)

<View className='index'>
    // 我是自定義生成的那張分享圖哦,會隨着數據變化而變化~
    <View className='save-view'>
      <Canvas className='poster' canvasId='poster' style='width:250px;height:200px;'></Canvas>
    </View>
   <CoverView>我是這個頁面要展示的內容
        <Button className='share-btn' open-type="share">我是分享按鈕</Button>
    </CoverView>
</View>

這里要注意:1.因為是分享轉發帶的圖片,按官方比例5:4。建議canvas的大小也是這個比例,例如500*400rpx;

      2.在首頁主要展示的內容用cover-view原生組件包起來,為的就是在進入頁面覆蓋掉canvas讓用戶看不到;

      3.這里建議最外層的cover-view采用fixed方式,因為有些手機識別z-index其實不是很好;

JS部分

  state: IState = {
    recordList: null, // 列表數據
    imgUrl: '', // 生成分享圖鏈接
  }; // data變量區


// 獲得canvas圖片信息
  ImageInfo(path: any) {
    return new Promise((resolve, reject) => {
      Taro.getImageInfo(
        {
          src: path,
          success: function (res) {
            resolve(res)
          },
          fail: function (res) {
            reject(res)
          }
        }
      )
    })
  }

  // 繪畫Canvas-分享圖
  drawTitle(datas: any, title: string) {
    new Promise((resolve, reject) => {
      let rpx = 0
      Taro.getSystemInfo({
        success: function (res) {
          rpx = res.windowWidth / 375
        }
      }) // 這里計算rpx是為了適配更多的手機,畢竟dpr值都不一樣。可以要也可以不要
      this.ImageInfo('https://static.jingzhuan.cn/WeChat/longtou/share-img-bg.png').then(res => { // 這里注意,因為canvas畫圖片是需要圖片信息的,即臨時路徑類,最好是先把背景圖放在網絡上再通過小程序API生成獲取路徑
        // 獲取畫布
        const cvsCtx = Taro.createCanvasContext('poster', this)
        cvsCtx.drawImage(res.path, 0, 0, 250 * rpx, 200 * rpx)  // 繪制背景底圖
        cvsCtx.setFontSize(16)
        cvsCtx.setFillStyle('#FFFFFF')
        cvsCtx.fillText(title, (250 - cvsCtx.measureText(title).width) * rpx / 2, 26 * rpx, 120 * rpx) // 計算標題文字所占寬度好做絕對居中計算
        for (let b = 0; b < 3; b++) {
          cvsCtx.setFontSize(14) // 設置字體大小
          cvsCtx.setFillStyle('#941D11') // 設置字體顏色
          cvsCtx.fillText(datas[b].name, 95 * rpx, (88 + b * 38) * rpx, 70 * rpx)
          cvsCtx.setFontSize(14)
          if (datas[b].rise_percent > 0) { // 判斷數據是否需要改變字體顏色
            cvsCtx.setFillStyle('#FB4949')
          } else {
            cvsCtx.setFillStyle('#00CC66')
          }
          cvsCtx.fillText(`${datas[b].rise_percent}%`, 180 * rpx, (88 + b * 38) * rpx, 70 * rpx) // 繪制文字所在位置
        }
        cvsCtx.draw(true)
      })
      resolve()
    }).then(() => {
      this.generateUrl() // 當頁面的canvas畫成功后就調取生成臨時路徑
    })
  }

  // 截取canvas生成臨時路徑
  async generateUrl() {
    const that = this
    setTimeout(() => {
      Taro.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 500, // 截取的寬度
        height: 400, // 截取的高度
        destWidth: 500, // 生成的圖片寬度
        destHeight: 400, // 生成的圖片高度
        canvasId: 'poster', // 生成對象的canvasid
        success: function (res) {
          that.goQiniu(res.tempFilePath) // 生成圖片成功后調取上傳到網絡上
        },
        fail: function (res) {
          console.log('繪制臨時路徑失敗')
        }
      })
    }, 1000) // 設置1秒定時是防止canvas畫一半,一般1秒是差不多的
  }

  // 上傳臨時圖片到七牛獲取網絡鏈接(這里是七牛SDK的上傳方法,其他服務器都有對應的,根據情況而改變哦~)
  async goQiniu(imgUrl: any) {
    const that = this
    const res = await getQiniu({
      key: 'sig'
    })
    qiniuUploader.upload(imgUrl, (res: any) => {
      let audioURL = (這里寫你們的服務器域名進行拼接,例如:https://www.baidu.com/) + res.key
      that.state.imgUrl = audioURL // 最后生成的網絡連接,是可以直接在網頁上打開看到圖片的,然后復制給到全局變量給分享的時候獲取
    }, (error: any) => {
      console.error('error: ' + JSON.stringify(error));
    },
      {
        uptoken: res.token,
        region: 'ECN', // 華東區
        key: `longtou/share/${Math.random().toString(36).slice(2, 10)}.png` // 自動生成隨機命名
      },
    )
  }

  // 自定義分享
  onShareAppMessage() {return {
      title: '我是分享標題~好不好看~',
      path: shareUrl,
      imageUrl: this.state.imgUrl, // 生成的分享圖賦值給到小程序自定義分享圖鏈接
      success: function () {
        // 轉發成功
        console.log(shareUrl)
      },
      fail: function () {
        // 轉發失敗
        console.log('轉發失敗')
      }
    }
  }

以上就是主要的思路代碼,最后注意要在進入頁面后就執行canvas畫圖,即在onlaod的時候執行drawTitle方法,這樣就避免在頁面加載完后用戶馬上點擊分享轉發canvas圖還沒畫完的情況

具體效果就如下(demo可能比較粗糙哈哈):


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM