小程式中繪製二維碼
阿新 • • 發佈:2018-11-20
小序
一個新的小程式專案,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存到微信伺服器及自己的伺服器裡就可以避免這個問題了