從上面截圖能夠看出,canvas的主體組成部分包括:javascript
背景圖css
微信頭像和暱稱信息html
小程序碼(小程序碼會攜帶分享者的信息)java
經過小程序提供的畫布,咱們能很容易的完成上面的整個海報的繪製。可是,canvas的繪製都是基於像素(px)級別的,可是在小程序中,咱們的預覽圖和最終生成的圖,都須要根據機型進行適配。git
底部彈出的模態框
模態框的實現見下面的XML內容,能夠看出具體組成以下:github
canvas外面套了一個modals,主要目的是讓預覽圖看起來在DOM的最上面canvas
shareCanvas就是咱們要繪製全部內容的畫布小程序
modals-cancel-black是一層半透明的蒙層,儘可能將頁面的其它元素遮蓋到它的下面api
其次就是一個關閉按鈕和相應的文字說明微信
<!-- 分享圖 -->
<view class="modals" hidden="{{isCanvasHidden}}">
<canvas canvas-id="shareCanvas" class="share-canvas" style="width:680rpx;height:1000rpx" hidden="{{isCanvasHidden}}"></canvas>
<view class="modals-cancel-black"></view>
<view class="cancal-canvas-container" bindtap="hideCanvas">
<image src="http://lc-adna4hf0.cn-n1.lcfile.com/13cb9cd1d79bbed4a47c.png" class="cancel-button"></image>
</view>
<view class="save-album-wrapper text-center">圖片已保存到相冊,可分享給好友</view>
</view>
複製代碼
.modals {
position: fixed;
z-index: 999;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.modals-cancel-black {
position: absolute;
z-index: 1000;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .8);
}
複製代碼
從動圖能夠發現,canvas的繪製是從點擊底部模態框的「生成分享圖」就開始了
drawShareCanvas: function () {
// 1.計算相對比例rpx
// 2.根據rpx繪製背景圖片
// 3.根據rpx繪製微信用戶信息部分
// 4.根據rpx繪製小程序碼部分
}
複製代碼
上述的1-4的步驟之間,可能存在具體的前後關係,能夠根據本身的狀況來定製前後順序
wx.getSystemInfo的返回值中能夠獲得移動端屏幕的具體寬度,小程序WXSS是以rpx做爲衡量單位,咱們的canvas寬高都是以rpx計算的寬高。可是canvas繪製時以px爲單位繪製。那麼咱們須要計算當前設備相對於375px的倍數。
後續的全部關於座標、長寬或者距離都須要乘以這個rpx倍數,才能達到適配全部倍數。
var rpx = 1
wx.getSystemInfo({
success (res) {
rpx = res.windowWidth / 375
// ...
}
})
複製代碼
由於背景圖稍微比較大,在繪製時,經過ctx.scale()方法將畫布總體都縮放了0.5倍
wx.showLoading({
title: '繪製背景圖'
})
wx.getImageInfo({
src: 'http://lc-adna4hf0.cn-n1.lcfile.com/33111f0ba3409c8fdef9.png',
success (res) {
// 隱藏背景圖loading
wx.hideLoading()
const ctx = wx.createCanvasContext('shareCanvas')
// 繪製背景圖
ctx.scale(0.5, 0.5)
ctx.drawImage(res.path, 0, 0, 680 * rpx, 1000 * rpx)
ctx.stroke()
// 繪製其它
},
fail () {
wx.showToast({
title: '背景圖獲取失敗',
icon: 'none'
})
}
})
複製代碼
微信我的圖像須要繪製成圓形的,能夠用CanvasContext.arc(...)來繪製一個圓弧實現。圓弧會有默認的黑色邊框。清除邊框使用ctx.setLineWidth(0)。若是須要自定義邊框顏色,可使用ctx.setStrokeStyle('red')來設定。
未指定ctx.clip()時,圖片不會被裁剪,看到的圖片仍是正方形。經過不指定裁剪的方式(註釋ctx.clip),能夠來精確肯定圖像的開始點的位置。圖像的開始繪製點位置爲:圓心橫座標 - 圓弧的半徑 = point - radius
let userinfo = wx.getStorageSync('userinfo')
if (userinfo) {
wx.showLoading({
title: '繪製用戶信息',
})
// 繪製我的信息部分
wx.getImageInfo({
src: userinfo.avatarUrl,
success (avatar) {
// 隱藏用戶信息loading
wx.hideLoading()
let radius = 50 * rpx
let point = 70 * rpx
ctx.scale(1, 1)
ctx.save()
ctx.beginPath()
ctx.setLineWidth(0)
ctx.arc(point, point, radius, 0, 2 * Math.PI)
ctx.setLineWidth(0)
ctx.closePath()
ctx.save()
ctx.clip()
ctx.drawImage(avatar.path, (point - radius), (point - radius), 100 * rpx, 100 * rpx)
ctx.restore()
},
fail (err) {
wx.showToast({
title: '獲取用戶頭像失敗',
icon: 'none'
})
}
})
// 暱稱
ctx.setFontSize(32 * rpx)
ctx.setFillStyle('white')
ctx.fillText(userinfo.nickName, 140 * rpx, 60 * rpx)
ctx.stroke()
// 稱謂
ctx.setFontSize(24 * rpx)
ctx.setFillStyle('#FEFEFE')
ctx.fillText('尚德學習大使', 140 * rpx, 100 * rpx)
ctx.stroke()
}
複製代碼
繪製小程序碼
小程序碼由於會攜帶分享着信息,須要經過調用後臺接口來動態生成,因此是異步的。能夠在生成期間loading給用戶返回進度。獲得小程序碼的url地址後,就能夠根據前面的繪製方法,找到小程序碼的位置繪製便可。
保存到系統相冊
全部繪製步驟完成後,此時還剩兩個事情是待作的。1、保存canvas畫布內容到系統相冊;2、顯示預覽圖。
根據整張圖的製做順序,小程序碼是最後一步完成的,因此小程序碼繪製到canvas後,算是全部繪製動做完成,須要執行
ctx.draw()
// 下一步?=> 保存圖片到相冊
saveAlbum()
// 顯示預覽圖
that.setData({
isCanvasHidden: false
})
複製代碼
按照上面的方式,咱們執行saveAlbum後發現,在開發工具上,每次都能正常的彈出保存圖片。可是在真機上測試時,偶爾會發現預覽圖已經出來了,可是到系統相冊查看,卻發現沒有生成想要的圖片。
經過查看小程序開發文檔才知道,wx.canvasToTempFilePath方法須要在ctx.draw的回調中執行(文檔地址)。因此,實際得這麼幹,畢竟人家定義接口的是大爺(嘻嘻)。
ctx.stroke()
ctx.draw(false, () => {
that.saveAlbum()
})
// 這個段也能夠放第四行以後
that.setData({
isCanvasHidden: false
})
複製代碼
保存到相冊的相關代碼
saveAlbum() {
var that = this
wx.canvasToTempFilePath({
x: 0,
y: 0,
canvasId: 'shareCanvas',
success: function (res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(saveRes) {
wx.showToast({
title: '保存成功',
icon: 'success'
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none'
})
that.hideCanvas()
}
})
}
})
}
複製代碼
不支持mp4預覽,轉換成gif太大了。
WeChat_20181031180605.mp4
小程序Canvas API: developers.weixin.qq.com/miniprogram…
本篇文章由一文多發平臺ArtiPub自動發佈