在小程序界裏,生成圖片分享到朋友圈這個功能,是如此得光芒耀眼,以致於各個小程序都趨之若鶩地前來跪倒在她的石榴裙下。不幸的是,微信爸爸並無提供給咱們很好很便捷的相關工具;偏偏相反,屏幕截屏的功能被殘忍丟進歷史的垃圾桶,只留下一個Canvas組件以及圍繞在其周圍的深淵巨坑們。css
因此咱們準備了一套名爲Painter的工具, 爲開發者提供一種簡單實用的「繪製」圖片的解決思路,讓開發者能夠自由地生成本身想要的圖片文件。前端
github傳送門:github.com/Kujiale-Mob…ios
若是直接使用canvas進行繪圖,那絕對是很酸爽的一次體驗,除了失控的代碼,還有無數的天坑。先來列舉一下canvas 中踩過的坑以及咱們的解決(或繞過)的方法。git
painter從實現上來說,是用了小程序的canvas做爲載體來實現以上功能的。而canvas有不少著名的坑。有的坑,咱們當心翼翼地繞了過去;有的坑,咱們仍是痛快淋漓地一腳踩了下去……github
如圖所示shell
經過右邊的相似於css又有點像json但其實上它是個js的寥寥幾行代碼,咱們繪製出了左邊的這樣的圖形,包含了背景圖片、文字、圖片、二維碼這四種經常使用的元素。json
Painter閱讀完代碼,繪製成圖片之後,會將圖片的連接返回給咱們。此時,咱們能夠將圖片上傳、保存到本地或者顯示在屏幕上。canvas
它能夠很方便地定製所須要的圖片,還能夠自由動態地給圖片更換風格。小程序
此外,小程序canvas.drawImage()方法在真機上不能繪製網絡圖片。而Painter 能夠解決這個問題,若是有繪製網絡圖片的需求也能夠考慮使用Painter。微信小程序
painter能夠下載網絡圖片到本地,並對下載到本地的網絡內容進行LRU管理。目前小程序容許的最大本地儲存爲10m,咱們默認painter可以使用的本地存儲爲6m,超出時會對本地存儲進行清理。若是須要自定義,能夠在/painter/lib/downloader.js中修改MAX_SPACE_IN_B屬性。
目前子 view 的 css 屬性支持 object 或 array。容許將幾個view公用的css屬性提取出來。
因爲palette 是以 js 承載的 json,因此你能夠在每個屬性中很方便的加上本身的邏輯。也能夠把某些屬性單獨提取出來,讓多個 palette 共用,作到模塊化。
demo項目使用submodule的方式進行管理,所以在clone時須要運行
git clone https://github.com/Kujiale-Mobile/Painter.git --recursive
複製代碼
clone完成後能夠看到目錄。其中,/pages/example中存放的是使用示例,/components/painter就是咱們所引入的功能組件。此外還有一個palette目錄,裏面存放是咱們所須要繪圖代碼。實際工做時,painter會調取card.js裏的信息,在圖片上繪製出相應的圖形,就像一支畫筆在調色板上調製蘸取了顏料,而後在畫布上創做同樣。
你能夠直接將demo裏的painter複製粘貼到本身的項目下,固然也能夠更爲優雅地運行一下這個代碼:
git submodule add https://github.com/Kujiale-Mobile/PainterCore.git painter
複製代碼
它會將Painter工具放置在你當前的目錄下。咱們推薦的作法是把它放在你的components下。
像其它的組件同樣,在須要引入Painter的頁面.json文件中添加:
"usingComponents":{
"painter":"/components/painter/painter"
}
複製代碼
在頁面的xml文件中調用painter組件,並傳入pallete規則的數據,以及繪製結束之後的回調。
<painter palette="{{data}}" bind:imgOK="onImgOK" bind:imgErr="onImgErr"/>
複製代碼
palette便是咱們的調色板數據,以json形式根據必定規範建立,詳細信息請移步下文。
bind:imgOK="onImgOK"
bind:imgErr="onImgErr"
複製代碼
數據傳入後,painter就會開始繪製,不管繪製成功或是失敗,都能在相應的回調方法裏獲取相關的信息,如:
說到底,Painter是一支畫筆工具,具體要讓這支畫筆畫什麼東西,還得由咱們,天資聰穎的程序猿們,來告訴它。告訴它應該畫什麼,在哪裏畫,畫的時候用什麼姿式……等等。這須要用一些別的手段,由於科學的實驗證實過,試圖用普通話這門語言跟它進行溝通,是不會有任何效果的。
每一塊調色板都它本身的總體屬性,它通常規定了整個繪圖範圍的大小、樣式、背景等
它處於整個json文件的最外層,須要指定如下幾個屬性:
屬性 | 解釋 |
---|---|
background | 背景,能夠是顏色值,也能夠是圖片連接,支持本地圖片連接和網絡圖片連接 |
width | 寬度 |
height | 高度 |
borderRadius | 圓角 |
views | 須要畫在圖上的其它元素,容許爲空,但不容許省略 |
示例代碼:
{
background: 'https://qhyxpicoss.kujiale.com/2018/06/12/LMPUSDAKAEBKKOASAAAAAAY8_981x600.png',
width: '654rpx',
height: '400rpx',
borderRadius: '20rpx',
views: []
}
複製代碼
畫完了調色板的總體屬性之後,就能夠向views中增長一些元素了。元素支持四種類型,用type字段進行區分分類。不一樣種類的view又要求提供有不一樣的數據,如image元素須要提供它的url,text元素須要提供text文字內容:
type | content | description | 私有css屬性 |
---|---|---|---|
image | url | 圖片資源地址,本地或網絡 | |
text | text | 文本元素,書寫文字 | fontSize:字體大小,color:文字顏色 |
rect | 無 | 矩形 | color:填充顏色 |
qrcode | content | 畫二維碼 | background:背景顏色,默認爲透明 |
除了各view的私有屬性以外,view還有一些公共屬性能夠設置:
屬性 | 做用 |
---|---|
left, top, right, bottom | 元素的位置 |
rotate | 旋轉角度,單位爲360度的度 |
borderRadius | 圓角,若是須要設置圖片爲原形,請設置該屬性爲寬或高的一半 |
align | 元素在水平方向的對齊方式,與left配合使用,可設置爲left, center, right,默認爲left。 |
控制元素的旋轉,以下圖,將一行文字順時針旋轉了6度。
{
type: 'text',
text: '酷家樂 移動前端',
css: {
left: '20rpx',
top: '50rpx',
fontSize: '40rpx'
},
},
複製代碼
效果:
代碼(圓形):
{
type: 'image',
url: this.cardInfo.avatar,
css: {
top: '48rpx',
left: '448rpx',
width: '192rpx',
height: '192rpx',
borderRadius:'96rpx',
},
},
複製代碼
方角-->8rpx圓角-->圓形
這個屬性值比較有意思,它被用來設置元素在水平方向的、相對於位置設置的對齊方式。
什麼意思呢?
好比說你設置了某元素的left爲100rpx,並設置align屬性爲left,那麼該元素的左端就與100rpx對齊;若設置align爲center,則該元素的中軸線與100rpx對齊。
在下面的例子中,三行文字的left都是230rpx,align分別爲left, center, right。紅線是橫座標爲230rpx的軸線。
即,當設置了align屬性的時候,left值表達的是元素屬性中align的位置。
代碼:
{
type: 'text',
text: '酷家樂 移動前端',
css: {
left: '330rpx',
top: '100rpx',
fontSize: '40rpx',
},
},
{
type: 'text',
text: '酷家樂 移動前端',
css: {
left: '330rpx',
top: '200rpx',
fontSize: '40rpx',
align: 'center'
},
},
{
type: 'text',
text: '酷家樂 移動前端',
css: {
left: '330rpx',
top: '300rpx',
fontSize: '40rpx',
align: 'right'
},
},
複製代碼
有了這個屬性,就能夠設置元素的對齊形式,完成下面的佈局要求了:
注意:align屬性請和left屬性配合使用,設置right值將形成錯誤。
當align屬性與rotate屬性同時存在時,元素的旋轉表現是以元素的中心點爲中心的。
目前 Painter 中支持兩種尺寸單位,px 和 rpx,表明的意思和小程序中一致。目前尚未很好地支持百分比的使用。
得到圖片的url後,能夠設置一個點擊按鈕,點擊保存到本地
onImgOK(e) {
this.imagePath = e.detail.path;
},
saveImage() {
wx.saveImageToPhotosAlbum({
filePath: this.imagePath,
})
},
複製代碼
按鈕綁定saveImage方法,點擊進行保存:
最後,利用Painter工具能夠生成不一樣樣式的朋友圈分享圖(下圖爲微信小程序 酷咖名片 線上版部分截圖)
painter是酷家樂前端在小程序的實際開發中自制的一套工具,目前在朋友圈分享、皮膚模板替換等方面都在使用,以爲用起來喜憂參半。開源出來你們分享。若是它能幫助到任何一我的,咱們都很是開心;咱們也很是歡迎並感謝提issure或pr,來告訴咱們一些咱們本身沒有能想到的東西,或者幫助解決Painter 中的大大小小的坑:
再一次傳送門:github.com/Kujiale-Mob…