小程序模板網(wǎng)

微信小程序朋友圈分享圖片生成方案實(shí)現(xiàn)

發(fā)布時(shí)間:2018-08-10 11:02 所屬欄目:小程序開(kāi)發(fā)教程

在小程序界里,生成圖片分享到朋友圈這個(gè)功能,是如此得光芒耀眼,以至于各個(gè)小程序都趨之若鶩地前來(lái)跪倒在她的石榴裙下。不幸的是,微信爸爸并沒(méi)有提供給我們很好很便捷的相關(guān)工具;恰恰相反,屏幕截屏的功能被殘忍丟進(jìn)歷史的垃圾桶,只留下一個(gè)Canvas組件以及圍繞在其周圍的深淵巨坑們。

所以我們準(zhǔn)備了一套名為Painter的工具, 為開(kāi)發(fā)者提供一種簡(jiǎn)單實(shí)用的“繪制”圖片的解決思路,讓開(kāi)發(fā)者可以自由地生成自己想要的圖片文件。

github傳送門(mén): github.com/Kujiale-Mob…

如果直接使用canvas進(jìn)行繪圖,那絕對(duì)是很酸爽的一次體驗(yàn),除了失控的代碼,還有無(wú)數(shù)的天坑。先來(lái)列舉一下canvas 中踩過(guò)的坑以及我們的解決(或繞過(guò))的方法。

canvas的坑

painter從實(shí)現(xiàn)上來(lái)講,是用了小程序的canvas作為載體來(lái)實(shí)現(xiàn)以上功能的。而canvas有很多著名的坑。有的坑,我們小心翼翼地繞了過(guò)去;有的坑,我們還是痛快淋漓地一腳踩了下去……

  1. 在微信版本6.6.6的某些ios機(jī)型上,canvas的clip()方法不能被restore。導(dǎo)致在這些機(jī)型上無(wú)法進(jìn)行切圓角的操作。迫于無(wú)奈在開(kāi)發(fā)中我們不得已拋棄了這些機(jī)型,用了一個(gè)if語(yǔ)句將這些機(jī)器的切圓角功能閹割了。。。
  2. 小程序的canvas提供了measuretText()方法,暫時(shí)只支持測(cè)量文本寬度,無(wú)法知道文字的具體高度。因此一些元素對(duì)齊的需求無(wú)法做到很漂亮。
  3. 在繪制圖片的時(shí)候,有幾率會(huì)發(fā)生很神奇的表現(xiàn),即canvas繪圖的時(shí)候位置出現(xiàn)整體偏差,造成最后生成的圖片有殘缺。這種情況大多數(shù)時(shí)候發(fā)生在onLoad中調(diào)用painter的情況下。我們處理的方法是對(duì)圖片的寬和高比例進(jìn)行檢測(cè),一旦出現(xiàn)異常,就重新繪制一遍。
  4. canvas不能繪制網(wǎng)絡(luò)圖片。canvas.drawImage(url)方法,給url傳入一個(gè)網(wǎng)絡(luò)鏈接,在模擬器上表現(xiàn)完美,然而在真機(jī)上無(wú)法繪制。我們?cè)赑ainter中引入了一套自己的網(wǎng)絡(luò)圖片下載后繪制的機(jī)制,并在其中加入了LRU存儲(chǔ)管理機(jī)制。
  5. canvas是原生組件,始終位于視圖的最上層,z-index設(shè)置對(duì)其無(wú)效。這個(gè)就不多說(shuō)了。。很多人應(yīng)該都踩過(guò)。
  6. canvas要進(jìn)行繪制,則canvas組件必須真實(shí)地被寫(xiě)在頁(yè)面上,而且其wx:if不能為false。不過(guò),允許把canvas組件放置在屏幕之外,如設(shè)置position:fixed;left:750rpx;。這一方法是可以解決5,6兩點(diǎn)問(wèn)題的黑科技

Painter的功能

如圖所示

通過(guò)右邊的類似于css又有點(diǎn)像json但其實(shí)上它是個(gè)js的寥寥幾行代碼,我們繪制出了左邊的這樣的圖形,包含了背景圖片、文字、圖片、二維碼這四種常用的元素。

Painter閱讀完代碼,繪制成圖片以后,會(huì)將圖片的鏈接返回給我們。此時(shí),我們可以將圖片上傳、保存到本地或者顯示在屏幕上。

它可以很方便地定制所需要的圖片,還可以自由動(dòng)態(tài)地給圖片更換風(fēng)格。

此外,小程序canvas.drawImage()方法在真機(jī)上不能繪制網(wǎng)絡(luò)圖片。而Painter 可以解決這個(gè)問(wèn)題,如果有繪制網(wǎng)絡(luò)圖片的需求也可以考慮使用Painter。

Painter其它優(yōu)勢(shì)

  1. painter可以下載網(wǎng)絡(luò)圖片到本地,并對(duì)下載到本地的網(wǎng)絡(luò)內(nèi)容進(jìn)行LRU管理。目前小程序允許的最大本地儲(chǔ)存為10m,我們默認(rèn)painter可使用的本地存儲(chǔ)為6m,超出時(shí)會(huì)對(duì)本地存儲(chǔ)進(jìn)行清理。如果需要自定義,可以在/painter/lib/downloader.js中修改MAX_SPACE_IN_B屬性。

  2. 目前子 view 的 css 屬性支持 object 或 array。允許將幾個(gè)view公用的css屬性提取出來(lái)。

  3. 由于palette 是以 js 承載的 json,所以你可以在每一個(gè)屬性中很方便的加上自己的邏輯。也可以把某些屬性單獨(dú)提取出來(lái),讓多個(gè) palette 共用,做到模塊化。

使用

demo下載

demo項(xiàng)目使用submodule的方式進(jìn)行管理,因此在clone時(shí)需要運(yùn)行

git clone https://github.com/Kujiale-Mobile/Painter.git --recursive

clone完成后可以看到目錄。其中,/pages/example中存放的是使用示例,/components/painter就是我們所引入的功能組件。此外還有一個(gè)palette目錄,里面存放是我們所需要繪圖代碼。實(shí)際工作時(shí),painter會(huì)調(diào)取card.js里的信息,在圖片上繪制出相應(yīng)的圖形,就像一支畫(huà)筆在調(diào)色板上調(diào)制蘸取了顏料,然后在畫(huà)布上創(chuàng)作一樣。

將Painter引入到自己的項(xiàng)目

你可以直接將demo里的painter復(fù)制粘貼到自己的項(xiàng)目下,當(dāng)然也可以更為優(yōu)雅地運(yùn)行一下這個(gè)代碼:

git submodule add https://github.com/Kujiale-Mobile/PainterCore.git painter

它會(huì)將Painter工具放置在你當(dāng)前的目錄下。我們推薦的做法是把它放在你的components下。

引入組件

像其它的組件一樣,在需要引入Painter的頁(yè)面.json文件中添加:

"usingComponents":{
  "painter":"/components/painter/painter"
}

組件調(diào)用

在頁(yè)面的xml文件中調(diào)用painter組件,并傳入pallete規(guī)則的數(shù)據(jù),以及繪制結(jié)束以后的回調(diào)。

<painter palette="{{data}}" bind:imgOK="onImgOK" bind:imgErr="onImgErr"/>

palette即是我們的調(diào)色板數(shù)據(jù),以json形式根據(jù)一定規(guī)范創(chuàng)建,詳細(xì)信息請(qǐng)移步下文。

繪制回調(diào)

bind:imgOK="onImgOK"
bind:imgErr="onImgErr"

數(shù)據(jù)傳入后,painter就會(huì)開(kāi)始繪制,無(wú)論繪制成功或是失敗,都能在相應(yīng)的回調(diào)方法里獲取相關(guān)的信息,如:

 

Pallette

說(shuō)到底,Painter是一支畫(huà)筆工具,具體要讓這支畫(huà)筆畫(huà)什么東西,還得由我們,天資聰穎的程序猿們,來(lái)告訴它。告訴它應(yīng)該畫(huà)什么,在哪里畫(huà),畫(huà)的時(shí)候用什么姿勢(shì)……等等。這需要用一些別的手段,因?yàn)榭茖W(xué)的實(shí)驗(yàn)證明過(guò),試圖用普通話這門(mén)語(yǔ)言跟它進(jìn)行溝通,是不會(huì)有任何效果的。

調(diào)色板屬性

每一塊調(diào)色板都它自己的整體屬性,它一般規(guī)定了整個(gè)繪圖范圍的大小、樣式、背景等

它處于整個(gè)json文件的最外層,需要指定以下幾個(gè)屬性:

示例代碼:

{
      background: 'https://qhyxpicoss.kujiale.com/2018/06/12/LMPUSDAKAEBKKOASAAAAAAY8_981x600.png',
      width: '654rpx',
      height: '400rpx',
      borderRadius: '20rpx',
      views: []
 }

view屬性

畫(huà)完了調(diào)色板的整體屬性以后,就可以向views中增加一些元素了。元素支持四種類型,用type字段進(jìn)行區(qū)分分類。不同種類的view又要求提供有不同的數(shù)據(jù),如image元素需要提供它的url,text元素需要提供text文字內(nèi)容:

除了各view的私有屬性之外,view還有一些公共屬性可以設(shè)置:

rotate

控制元素的旋轉(zhuǎn),如下圖,將一行文字順時(shí)針旋轉(zhuǎn)了6度。

{
    type: 'text',
    text: '酷家樂(lè) 移動(dòng)前端',
    css: {
     left: '20rpx',
     top: '50rpx',
     fontSize: '40rpx'
   },
},

效果:

 

borderRadius

代碼(圓形):

{
          type: 'image',
          url: this.cardInfo.avatar,
          css: {
            top: '48rpx',
            left: '448rpx',
            width: '192rpx',
            height: '192rpx',
            borderRadius:'96rpx',
          },
        },

方角-->8rpx圓角-->圓形

 

align

這個(gè)屬性值比較有意思,它被用來(lái)設(shè)置元素在水平方向的、相對(duì)于位置設(shè)置的對(duì)齊方式。

什么意思呢?

比如說(shuō)你設(shè)置了某元素的left為100rpx,并設(shè)置align屬性為left,那么該元素的左端就與100rpx對(duì)齊;若設(shè)置align為center,則該元素的中軸線與100rpx對(duì)齊。

在下面的例子中,三行文字的left都是230rpx,align分別為left, center, right。紅線是橫坐標(biāo)為230rpx的軸線。

即,當(dāng)設(shè)置了align屬性的時(shí)候,left值表達(dá)的是元素屬性中align的位置。

代碼:

{
          type: 'text',
          text: '酷家樂(lè) 移動(dòng)前端',
          css: {
            left: '330rpx',
            top: '100rpx',
            fontSize: '40rpx',
          },
        },
        {
          type: 'text',
          text: '酷家樂(lè) 移動(dòng)前端',
          css: {
            left: '330rpx',
            top: '200rpx',
            fontSize: '40rpx',
            align: 'center'
          },
        },
        {
          type: 'text',
          text: '酷家樂(lè) 移動(dòng)前端',
          css: {
            left: '330rpx',
            top: '300rpx',
            fontSize: '40rpx',
            align: 'right'
          },
        },

有了這個(gè)屬性,就可以設(shè)置元素的對(duì)齊形式,完成下面的布局要求了:

注意:align屬性請(qǐng)和left屬性配合使用,設(shè)置right值將造成錯(cuò)誤。

align與rotate

當(dāng)align屬性與rotate屬性同時(shí)存在時(shí),元素的旋轉(zhuǎn)表現(xiàn)是以元素的中心點(diǎn)為中心的。

 

尺寸單位

目前 Painter 中支持兩種尺寸單位,px 和 rpx,代表的意思和小程序中一致。目前還沒(méi)有很好地支持百分比的使用。

保存圖片演示

獲得圖片的url后,可以設(shè)置一個(gè)點(diǎn)擊按鈕,點(diǎn)擊保存到本地

onImgOK(e) {
    this.imagePath = e.detail.path;
  },

  saveImage() {
    wx.saveImageToPhotosAlbum({
      filePath: this.imagePath,
    })
  },

按鈕綁定saveImage方法,點(diǎn)擊進(jìn)行保存:

 

生成朋友圈分享圖

最后,利用Painter工具可以生成不同樣式的朋友圈分享圖(下圖為微信小程序 酷咖名片 線上版部分截圖)


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開(kāi)源 碼云倉(cāng)庫(kù):starfork
本文地址:http://u-renovate.com/wxmini/doc/course/24705.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢