由於最近接觸到商務類型的小程序開發較多,其中必不可少的一個功能就是小程序分享海報的繪制,海報繪制無非就是將元素在 canvas 上繪制並生成圖片,常用的方法有 Wxml2Canvas 及 Painter。由於 Wxml2Canvas 的局限性較大,而且繪制出來的效果比較一般,如果較為簡單的海報可以嘗試使用,本文着重分享一下 Painter 以及使用方法。
Painter 的原理相當於我們把需要出現在畫板的元素列出來傳給 Painter,它就會調用 Pen 去將元素一一繪制出來。Painter 支持繪制的格式有 text(文本)、image(圖片)、rect(矩形)、qrcode(二維碼)。
並且 Painter 的強大在於它不僅可支持圓角、陰影、邊框、漸變色的繪制,還可支持旋轉(rotate)、分辨率調整,功能十分強大,可滿足業務中的大部分需求。相關文檔及安裝方式:https://github.com/Kujiale-Mobile/Painter
Painter 中的元素基本都是以絕對定位形式存在的,但也可支持相對定位,操作起來也不麻煩,只需要給相對元素設置一個 id,后續元素即可根據該元素進行相對偏移。至於元素的層級關系,由於 Painter 中沒有 z-index 用於控制層級,所以采用的方式是出現在后面的元素則層級較高。
下面簡單給一個 demo,方便讀者理解:
// wxml 文件 // drawPosterData 相當於畫板上的元素,需要手動配置 // widthPixels 為生成的圖片的像素寬度,如不傳則根據模版動態生成 // sharePosterDone 當 canvas 繪制完畢時會觸發該鈎子函數,通過讀取 res.detail.path 可獲取生成圖片的臨時存儲路徑 // tips: 該組件會占用一定空間,可根據實際布局將該組件隱藏。本項目中將其寬高都設置為 0,position 改為 absolute,達到隱藏效果 <painter-2d palette="{{drawPosterData}}" bind:imgOK="sharePosterDone" widthPixels="1080" class="hidden" />
palette 配置 demo:
export const initPosterConfig = function(data) { const config = Object.create(null) config.background = '#000000' config.width = '540rpx' config.height = '958rpx' config.views = [ // background image { type: 'image', url: 'https://cloud-minapp-37887.cloud.ifanrusercontent.com/1lJ5j1YODUdcYLH3.jpg', css: { width: '100%', height: '100%', top: '0', }, }, // cover image { type: 'rect', css: { width: '394.3rpx', height: '302.3rpx', top: '196rpx', left: '76rpx', rotate: '7', color: '#FFFFFF', shadow: '0px 10px 15px rgba(119, 7, 9, 0.25)', }, }, { type: 'image', url: data.cover_image, css: { width: '371.78rpx', height: '279.76rpx', top: '207.44rpx', left: '87.44rpx', rotate: '7', mode: 'scaleToFit', }, }, // user info { type: 'image', url: data.created_by.avatar, css: { width: '76rpx', height: '76rpx', borderRadius: '100%', top: '542rpx', left: '104rpx', }, }, { type: 'text', text: data.created_by.nickname, css: { top: '554rpx', left: '196rpx', color: '#606060', fontSize: '21rpx', lineHeight: '30rpx', fontWieght: 'bold', // width: '200rpx', // maxLines: '1', }, }, // rank { type: 'text', text: 'No.' + `${data.serial_number}`.padStart(5, 0), css: { top: '586rpx', left: '198rpx', fontSize: '22rpx', lineHeight: '30rpx', color: '#D8D7D7', fontWeight: 'bold', }, }, // congratulation { type: 'text', text: data.congratulation.split(',').join('\n'), css: { top: '632rpx', left: '104rpx', fontSize: '40rpx', lineHeight: '50rpx', maxLines: '2', color: '#BC8D92', }, }, // tips { type: 'text', text: '識別二維碼進入活動\n為她點贊', css: { top: '796rpx', left: '104rpx', fontSize: '18rpx', lineHeight: '30rpx', maxLines: '2', color: '#606060', }, }, // 分享二維碼 { type: 'image', url: data.qrcode, css: { width: '124rpx', height: '124rpx', right: '22rpx', bottom: '32rpx', borderRadius: '100%', borderWidth: '4rpx', borderColor: '#FFFFFF', }, }, ] return config }
至於 config 的配置,根據設計稿來完成就行啦。繪制完成后拿到臨時存儲路徑,用個 image 標簽將圖片展示即可。圖片保存請參考微信官方文檔 wx.saveImageToPhotosAlbum。
放幾個 demo 展示效果: