1. 程式人生 > >小程式中繪製二維碼

小程式中繪製二維碼

小序

一個新的小程式專案,VIP親子年卡(以下簡稱客戶端), 和一個對應的商家端, 在做的過程中有一個需求,在客戶端展示二維碼, 商家端掃碼獲取資訊。

既然需求已經訂了,就搞一搞繪製二維碼

先寫元素

<view class='hxm-bg'>
    <view class='hxm-show'>
        <view class='canvas-img'>
            <image src="{{imagePath}}" mode='widthFix'></image>
            <view class='fs-28'>參加活動請出示核銷碼</view>
        </view>
    </view>
</view>
<view class="canvas-box">
    <!-- 正方形 寬高一致-->
    <canvas hidden="{{canvasHidden}}" style="width: 686rpx;height: 686rpx;background:#f1f1f1;" canvas-id="mycanvas"/>
</view>

樣式

.canvas-box{
  position: fixed;
  left: -9999em; /* 讓canvas放在可視範圍外*/
}
.canvas-img{
  height: 500rpx;
  width: 500rpx;
  margin: 0 auto;
  position: relative;
}
.canvas-img image {
  z-index: 99;
  width: 100%;
  height: 100%;
}

這生成圖片的樣式,之前我試過用position各種佈局定位,發現還是不稱心,最後寫成這種

邏輯

qrcode在此處下載http://davidshimjs.github.io/qrcodejs/

const QR = require("../../utils/qrcode.js"); // 引用js
data: {
    canvasHidden: false, // canvas顯示/隱藏
    imagePath:'', // 預設圖片路徑
    qrCodeContent: ''// 預設二維碼生成文字 - 後端返引數
},
onload () {
    this._htrequest()
},
_htrequest () { // 這是一個介面
    let _t = this
    wx.request({
        ...,
        success (res) {
            let size = _t.setCanvasSize();//動態設定畫布大小
            let imagePath = wx.getStorageSync('ocs_mini_qrCodeContentImgs')
            if (imagePath) { // 取快取,增強體驗 
                _t_.setData({
                    imagePath: wx.getStorageSync('ocs_mini_qrCodeContentImgs') || ''
                })
            } else { // 不存在則生成
                let initUrl = res.qrCodeContent;
                _t.createQrCode(initUrl, "mycanvas", size.w, size.h);
            }
        }
    })
    
},
setCanvasSize () { //適配不同螢幕大小的canvas
    var size={};
    try {
        var res = wx.getSystemInfoSync();
        var scale = 750/686; // canvas的適配比例;設計稿是750寬 686canvas寬度
        var width = res.windowWidth/scale;
        var height = width; // canvas畫布為正方形
        size.w = width;
        size.h = height;
      } catch (e) {
        console.log("獲取裝置資訊失敗"+e);
      } 
    return size;
},
createQrCode (url,canvasId,cavW,cavH) {
    //呼叫外掛中的draw方法,繪製二維碼圖片
    QR.api.draw(url,canvasId,cavW,cavH)
    setTimeout(() => { this.canvasToTempImage();},1000);
},
canvasToTempImage () { //獲取生成canvas檔案的臨時路徑,存入data中
    let _t = this;
    wx.canvasToTempFilePath({
      canvasId: 'mycanvas', // 對應元素中的canvasid
      success (res) {
          var tempFilePath = res.tempFilePath;
          _t.setData({
              imagePath: tempFilePath,
            // canvasHidden:true
          });
          wx.setStorageSync('ocs_mini_qrCodeContentImgs', tempFilePath)
          wx.hideLoading()
      },
      fail: function (res) {
          console.log(res);
      }
    });
}

這時候會有一個問題, 當你已經成功一次了,快取記錄了, 下次過一陣取的時候,這個圖片是會有時效的, 下次的這個路徑可能就已經失效了

// wxml 為image圖片元素繫結一個error元素
<image src="{{imagePath}}" mode='widthFix'  binderror='imageError'></image>
// js
imageError (e) { // 當圖片路徑失效時,再次生成臨時圖片路徑
    var size = this.setCanvasSize();//動態設定畫布大小
    this.createQrCode(this.data.userInfo.qrCodeContent, "mycanvas", size.w, size.h);
},

還有一個解決方案, 在wx.canvasToTempFilePath成功時候將圖片路徑wx.upload存到微信伺服器及自己的伺服器裡就可以避免這個問題了

嗖嗖嗖~ 傳送門