轉自IMWeb社區,做者:結一,原文連接git
爲了吸引更多的用戶,設計好一個分享海報仍是頗有必要的。而小程序要生成一個海報仍是有點坑的,下面分享下咱們打卡小程序的一些經驗。github
分享海報的效果圖以下:web
製做要求:canvas
因爲看到的彈窗圖片與保存的圖片是兩種大小,因此一開始看了些網上的其餘教程,建議是搞兩個 canvas 一個大的一個小的。實際過程當中,採用了一個大的 canvas ,讓其偏離視窗顯示區域(不可見)並生成臨時文件,彈窗的圖片再使用 img 組件,引入臨時文件,設置其高度;而保存的時候則直接下載臨時文件。小程序
雖然是實現了,可是後來在優化的過程當中,這個方案也從新設計了。下面具體介紹下優化過的方案:api
因爲最後海報的圖片大小爲 iphone 6 的兩倍圖(750 * 1334),因此這裏彈窗的圖片也便是 canvas 的大小,設計爲對應的尺寸的某個比例。bash
彈窗圖片的高度 = 視窗的高度 - 上下留白 - 按鈕的高度 - 圖片與按鈕的距離
imgHeight = 100vh - 40rpx * 2 - 50rpx - 15rpx
彈窗圖片的寬度 / 彈窗圖片的高度 = 750 / 1334
彈窗圖片的寬度 = (750 / 1334) * 彈窗圖片的高度
複製代碼
因爲像素只能是整數,因此這樣繪製出來的圖片可能底部會有1px的空白,因此在設置高度的時候能夠再減掉 1px,這不會影響視覺效果。微信
若是是網絡圖片,繪製背景圖以前必定要先下載該圖片,可經過 wx.getImageInfo
或 wx. downloadFile
下載圖片,下載成功後將其塞進臨時地址,而後使用 wx canvas 的 drawImage
繪製。注意若是地址是 base64 的話, gif 是不行的。網絡
繪製二維碼換了好幾個庫,每一個在安卓下面生成的二維碼都會頻現失敗。查了好些資料,說是安卓繪製的時候要設置個 setTimeout,因而最終選擇了weapp-qrcode,修改了其繪製的函數,增長了setTimeout(還真別說,加上二維碼繪製就成功了)。app
ctx.draw(false, function (e) {
setTimeout(() => { // 修改增長的
options.callback && options.callback(e)
}, 20);
})
複製代碼
另:目前這些繪製小程序二維碼的庫都是在一個單獨的新 canvas 中完成的,只要對源碼稍做修改,就能夠提供另外一個接口,直接在一個現有的 canvas (表示 canvas 中一開始繪製了其餘內容) 中繪製。
若是二維碼掃不出來,則表示二維碼繪製出了問題。但安卓微信 6.7.2 版本自己有個 bug,二維碼自己是沒有問題,它卻不能識別。不過升級下微信版本就行了。
saveImageToPhotosAlbum
接口保存圖片saveImageToPhotosAlbum
接口保存圖片// 先嚐試保存
trySaveImg() {
const _this = this;
// 獲取用戶是否開啓用戶受權相冊
wx.getSetting({
success(res) {
// 若是沒有則獲取受權
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
_this.saveImg();
},
fail() {
// 若是用戶拒絕過或沒有受權,則再次打開受權窗口
// (ps:微信api又改了如今只能經過button才能打開受權設置,之前經過openSet就可打開,下面有打開受權的button彈窗代碼)
wx.showModal({
title: '獲取權限失敗',
content: '是否打開設置頁,容許小程序保存圖片到你的相冊',
success: () => {
wx.openSetting({
success (sRes) {
if (sRes.authSetting['scope.writePhotosAlbum']) {
setTimeout(() => {
_this.saveImg();
}, 200);
}
},
});
},
});
},
});
} else {
// 有則直接保存
_this.saveImg();
}
},
});
},
// 正式保存
saveImg() {
const { tempImgPath } = this.data;
wx.showLoading({
title: '正在保存中...', // 提示的內容,
mask: true, // 顯示透明蒙層,防止觸摸穿透,
});
wx.saveImageToPhotosAlbum({
filePath: tempImgPath,
success() {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000,
mask: true,
});
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none',
duration: 2000,
mask: true,
});
},
});
},
複製代碼
經實踐測試整個繪製過程其實仍是很快的,可是若是有保存臨時文件操做( wx.canvasToTempFilePath
),那麼這個操做通常得佔一半時間左右。除此以外,有個 measureText api,用來測量文字的長度,這個在實現自動換行的時候用獲得,可是比較耗性能。