剛作完一個微信小程序的項目,如今對項目裏的一些功能進行整理,這篇文章記錄下如何在小程序裏實現生成帶有二維碼的海報,並保存到用戶相冊。html
以此文章記錄,便於後續項目使用。vue
項目是基於mpvue作的。canvas
每一個用戶能夠生成一個屬於本身的推廣二維碼,拉新後記錄推廣人。小程序
生成的海報最終效果也不復雜,如圖:微信小程序
經過查閱微信小程序的文檔得知,能夠藉助於小程序提供的canvas繪圖功能根據設計圖來繪製個canvas圖,而後經過保存圖片到相冊這個API把圖片保存到用戶的手機相冊。api
海報中有些內容是固定不變的,好比背景圖、邀請話術以及下面長按圖片的提示語,而還有些內容是動態的,好比用戶名和小程序碼,不一樣項目需求不同,但都會有變更和不變兩類內容,而後咱們根據設計圖一點一點把內容繪製到圖上就行啦。bash
知道要作什麼了,那麼咱們來羅列下要作的事情(吉德林法則有云:把要解決的問題清清楚楚的列下來,問題就解決了一半)微信
<canvas class="cv-ct-canvas" canvas-id="cv-pic"></canvas>
.cv-ct-canvas {
position: absolute;
left: 800rpx;
width: 300px;
height: 500px;
}
複製代碼
const { tempFilePath: bg } = await this.downloadFile('$(STATICFILE_URL)/prom-share-bg.png')
let name = this.userInfo.NickName;
// 下載圖片到本地
const { tempFilePath } = await this.downloadFile(this.qrcodeUrl);
複製代碼
這裏要說明下,這個downloadFile方法是把微信的downloadFile方法進行了同步處理,其實很簡單,就是用個Promise包裹一下。async
const ctx = wx.createCanvasContext("cv-pic");
// 填充背景色
ctx.setFillStyle("#f8f8f8");
ctx.fillRect(0, 0, 300, 400);
ctx.fill();
ctx.setFillStyle("#ffffff");
ctx.fillRect(0, 400, 300, 100);
ctx.fill();
// 填充背景圖
ctx.drawImage(bg, 30, 20, 240, 365);
// 寫入名字
ctx.setFontSize(15);
ctx.setFillStyle("#FFF9F0");
ctx.fillText(name, 61, 300);
// 寫兩行提示
ctx.setFillStyle("#322F30");
ctx.setFontSize(14);
ctx.fillText("長按識別小程序碼", 33, 440);
ctx.fillText("超值禮包等你來搶", 33, 465);
// 填充小程序碼
ctx.drawImage(tempFilePath, 0, 0, 280, 280, 200, 410, 80, 80);
const that = this;
// 把canvas圖保存到臨時目錄
ctx.draw(false, function() {
wx.canvasToTempFilePath({
canvasId: "cv-pic",
success(res) {
let url = res.tempFilePath;
that.savePic = url;
}
});
});
複製代碼
在最後用canvasToTempFilePath把圖片先保存到了臨時目錄,並把臨時目錄的地址賦值給了savePic,由於界面上要展現這個圖,因此在界面上會有個Image標籤,這個標籤的地址就是savePic。函數
if (!this.savePic) return;
const that = this;
wx.saveImageToPhotosAlbum({
filePath: this.savePic,
success: function() {
that.showSaveCode = false;
wx.showToast({
title: "保存成功",
icon: "success",
duration: 2000
});
},
fail: function () {
that.getWriteToAlbumSetting()
}
});
複製代碼
對於最後這個fail裏面的getWriteToAlbumSetting方法,下面做解釋。
async getWriteToAlbumSetting() {
// this.getSetting 方法也是對wx.getSetting的一個同步封裝處理
let status = await this.getSetting('writePhotosAlbum')
// 由於用戶第一次進行操做的時候,受權狀態爲undefined,只有在明確拒絕過的時候纔會是false
if (status === true || status === undefined) {
this.canWriteToAlbum = true
} else {
this.canWriteToAlbum = false
}
}
複製代碼
<div class="cv-save" @click="saveToPhotosAlbum" v-if="canWriteToAlbum">保存圖片</div>
<div class="cv-save" @click="openAlbumSetting" v-else>保存圖片</div>
複製代碼
至於爲何要這麼作,固然仍是由於小程序的限制啦。若是用戶拒絕過受權,再次點擊保存按鈕,要彈出受權界面,而微信明確要求,彈出受權界面必須是用戶直接點擊按鈕觸發,因此只能這樣實現了。openAlbumSetting代碼以下:
async openAlbumSetting() {
// 仍是對微信API的同步封裝
let status = await this.openSetting('writePhotosAlbum')
// false表示又拒絕了
if (status === false) return
// 只有明確受權了才進行保存到相冊的操做
this.canWriteToAlbum = true
this.saveToPhotosAlbum()
}
複製代碼
這篇文章除了記錄對於生成分享海報的實現外,主要還說明了如何處理用戶拒絕受權的狀況,這裏雖然只說了對於拒絕保存圖片的受權,但對於其餘操做的受權拒絕處理也能夠這樣。
第一次寫文章,有點亂,之後慢慢練習吧~~~