基於Taro的微信小程序分享圖片功能實踐

前言

在各種小程序(微信、百度、支付寶)、H5、NativeApp 紛紛擾擾的當下,給大家強烈安利一款基於React的多終端開發利器:京東Taro(泰羅·奧特曼),Taro致力於多終端統一解決方案,一處代碼,多處運行。

Taro支持以React語言開發小程序,支持CSS預處理器,支持實時編譯更新,支持NPM,等等等等,簡直不要太爽!

微信小程序分享圖片功能是經常在小程序業務中出現的,比如學習打卡分享,推廣會員分享,推廣商品分享等等。因爲小程序是不支持直接分享圖片到朋友圈的,一般操作爲:

  1. 生成包含小程序碼(當前也可以是其他特定的信息)的圖片;
  2. 用戶點擊保存圖片,下載到本地,再發布到朋友圈;
  3. 其他用戶長按識別該小程序碼,進入當前小程序。

今天胡哥給大家分享下,基於Taro框架實現微信小程序分享圖片功能的實踐。

一、搭建Taro項目框架,創建微信小程序

1. 安裝taro腳手架工具

npm install -g @tarojs/cli

2. 初始化taro項目

taro init taro-img-share

3. 編譯項目,開啓Dev模式,生成小程序 -- dist目錄

npm run dev:weapp

4. 微信開發者工具,創建小程序,選擇項目根目錄爲taro-img-share下的dist目錄

二、小程序分享圖片功能實踐 --- 打卡圖片分享功能

先上圖,再說話

效果圖
點擊保存到相冊

這是重點:使用Canvas繪製圖片並展示,保存圖片到相冊

drawImage()方法負責繪製展示,saveCard()方法負責下載圖片到相冊

src/pages/index/index.js

import Taro, { Component } from '@tarojs/taro'
// 引入對應的組件
import { View, Text, Button, Canvas } from '@tarojs/components'
import './index.scss'

export default class Index extends Component {

  config = {
    navigationBarTitleText: '首頁'
  }

  /**
  * 初始化信息
  */
  constructor () {
    this.state = {
      // 用戶信息
      userInfo: {},
      // 是否展示canvas
      isShowCanvas: false
    }
  }

  /**
   * getUserInfo() 獲取用戶信息
   */
  getUserInfo (e) {
    if (!e.detail.userInfo) {
      Taro.showToast({
        title: '獲取用戶信息失敗,請授權',
        icon: 'none'
      })
      return
    }
    this.setState({
      isShowCanvas: true,
      userInfo: e.detail.userInfo
    }, () => {
      // 調用繪製圖片方法
      this.drawImage()
    })
  }

  /**
   * drawImage() 定義繪製圖片的方法
   */
  async drawImage () {
    // 創建canvas對象
    let ctx = Taro.createCanvasContext('cardCanvas')
    
    // 填充背景色
    let grd = ctx.createLinearGradient(0, 0, 1, 500)
    grd.addColorStop(0, '#1452d0')
    grd.addColorStop(0.5, '#FFF')
    ctx.setFillStyle(grd)
    ctx.fillRect(0, 0, 400, 500)

    // // 繪製圓形用戶頭像
    let { userInfo } = this.state
    let res = await Taro.downloadFile({
      url: userInfo.avatarUrl
    })
    ctx.save()
    ctx.beginPath()
    // ctx.arc(160, 86, 66, 0, Math.PI * 2, false)
    ctx.arc(160, 88, 66, 0, Math.PI * 2)
    ctx.closePath()
    ctx.clip()
    ctx.stroke()
    ctx.translate(160, 88)
    ctx.drawImage(res.tempFilePath, -66, -66, 132, 132)
    ctx.restore()

    // 繪製文字
    ctx.save()
    ctx.setFontSize(20)
    ctx.setFillStyle('#FFF')
    ctx.fillText(userInfo.nickName, 100, 200)
    ctx.setFontSize(16)
    ctx.setFillStyle('black')
    ctx.fillText('已在胡哥有話說公衆號打卡20天', 50, 240)
    ctx.restore()

    // 繪製二維碼
    let qrcode = await Taro.downloadFile({
      url: 'https://upload-images.jianshu.io/upload_images/3091895-f0b4b900390aec73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/258/format/webp.jpg'
    })
    ctx.drawImage(qrcode.tempFilePath, 70, 260, 180, 180)

    // 將以上繪畫操作進行渲染
    ctx.draw()
  }

  /**
   * saveCard() 保存圖片到本地
   */
  async saveCard () {
    // 將Canvas圖片內容導出指定大小的圖片
    let res = await Taro.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 400,
      height: 500,
      destWidth: 360,
      destHeight: 450,
      canvasId: 'cardCanvas',
      fileType: 'png'
    })
    let saveRes = await Taro.saveImageToPhotosAlbum({
      filePath: res.tempFilePath
    })
    if (saveRes.errMsg === 'saveImageToPhotosAlbum:ok') {
      Taro.showModal({
        title: '圖片保存成功',
        content: '圖片成功保存到相冊了,快去發朋友圈吧~',
        showCancel: false,
        confirmText: '確認'
      })
    } else {
        Taro.showModal({
        title: '圖片保存失敗',
        content: '請重新嘗試!',
        showCancel: false,
        confirmText: '確認'
      })
    }
  }

  render () {
    let { isShowCanvas } = this.state
    return (
      <View className='index'>
        <Button onGetUserInfo={this.getUserInfo} openType="getUserInfo" type="primary" size="mini">打卡</Button>
        {/* 使用Canvas繪製分享圖片 */}
        {
          isShowCanvas && 
            <View className="canvas-wrap">
              <Canvas 
                id="card-canvas"
                className="card-canvas"
                style="width: 320px; height: 450px"
                canvasId="cardCanvas" >
              </Canvas>
              <Button onClick={this.saveCard} className="btn-save" type="primary" size="mini">保存到相冊</Button>
            </View> 
        }
      </View>
    )
  }
}

src/pages/index/index.sass

index.js組件中的css樣式
.index {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.canvas-wrap {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  .btn-save {
    margin-top: 40rpx;
  }
}

注意事項

設置Taro支持ES6的async/await

  1. 下載@tarojs/async-await

    npm install -D @tarojs/async-await
  2. app.js中引入

    import '@tarojs/async-await'

開發完畢,發佈小程序

  1. 執行打包,生成最終的小程序源碼

    npm run build:weapp
  2. 發佈小程序

    點擊微信開發者工具上傳按鈕,上傳小程序,然後在微信小程序平臺發佈小程序即可。

小結

  1. 本文着重介紹了使用Taro實現小程序生成打卡圖片,保存相冊,分享圖片功能的開發原理與實踐步驟,各位童鞋可參考並結合自己的實際業務進行擴展開發。
  2. 本文併爲深入的對不同手機進行圖片適配,部分值也是設置的固定值(如填充文字的開始座標與填充的文字長度、大小),並未做比例響應。需要進一步交流的小夥伴,可以關注胡哥有話說公衆號,持續關注相關文章,也可直接在文章留言交流。
  3. 無論是使用何種框架如Taro、mpvue、wepy等開發小程序分享圖片功能,原理都是一樣的,只不過是在調用方法以及處理邏輯時需要進行響應的小調整
掌握業務功能實現原理,是制勝一切的法寶!

如何獲取該案例的源代碼

  1. 關注胡哥有話說公衆號
  2. 回覆關鍵字Taro即可,會收到項目源碼地址

後記

以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得收藏轉發、點擊右下角按鈕在看,推薦給更多小夥伴呦,歡迎多多留言交流...

胡哥有話說,一個有技術,有情懷的胡哥!京東開放平臺首席前端攻城獅。與你一起聊聊大前端,分享前端系統架構,框架實現原理,最新最高效的技術實踐!

長按掃碼關注,更帥更漂亮呦!關注胡哥有話說公衆號,可與胡哥繼續深入交流呦!

胡哥有話說

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章