ionic3開發——記一個使用自定義icon的方法

最近在使用ionic3Angular開發一款App。開發體驗仍是挺好的。期間遇到如何在項目中使用自定義圖標字體文件的問題,通過研究,找到了一個解決方法,記錄一下。css

問題描述

ionic項目提供了一套豐富的圖標庫,在ionic3中也進行了升級。雖然很實用,可是在實際項目中,仍是須要根據視覺稿來增長圖標。html

一般,咱們都會使用@font-face導入自定的字體文件。那麼咱們怎麼將這些圖標融入到ionic3的項目中去呢?ios

下面以ionic3中的tabs組件做爲例子,提出一種解決方式。git

話說問題是解決了,可是看起來其實並不優雅,不過能解決問題。=.=||github

理解ionic3中的圖標組件

ionic icon的使用

ionic3中提供圖標使用的方式有很多,其中很是重要的組件是:ion-icon,基本的使用方法以下:web

<ion-icon name="heart" ></ion-icon>

name屬性是圖標的名稱,這樣ionic就會在這個標籤處渲染生成一個圖標。其餘的用法,還有:chrome

  • 根據不一樣的設計風格使用不一樣的圖標(ios or md-->Material Design)瀏覽器

  • 設置圖標的不一樣狀態app

  • 做爲特定組件的屬性框架

ionic也爲本身的圖標庫提供了一個預覽的頁面,Ionicons

tabs組件中使用icon

在例子中,tabs組件使用圖標的方式,是這樣的:

<ion-tabs>
    <ion-tab tabIcon="heart" [root]='tabPage1'></ion-tab>
    <ion-tab tabIcon="alarm" [root]="tabPage2"></ion-tab>
    <ion-tab tabIcon="at" [root]="tabPage3"></ion-tab>
</ion-tabs>

經過設置tabIcon屬性,就可使用圖標庫中指定的圖標。

仔細看一下渲染後的html結構,你會發現,ion-tab實際上是在模板中加入了ion-icon組件:

渲染後的tabs組件使用了ion-icon組件

那麼,ionic是如何根據一個name屬性,就連接到他的圖標庫中的圖標呢?

ionic使用圖標的原理

因爲ionic3使用了Angular做爲框架開發,所以ion-icon要麼是組件,要麼是指令。因此咱們看看它的源碼,是如何實現圖標文件的使用的。

源碼傳送門:ion-icon

從源碼中咱們能夠看到,ionic把ion-icon定義爲一個指令,有三個步驟:

  1. 進行平臺風格(iosmd)判斷和狀態的判斷。

  2. 根據判斷的結果,將輸入的圖標名稱,進一步組合成爲以下形式的格式化文本

    ion-{平臺風格標識}-{圖標名}-{修飾}
  3. 將上一步獲得的格式文本,添加到元素的class屬性中。

至此,也很好理解了,經過一個css類,就可使用圖標庫中的字體定義(@font-face)

ionic將本身的圖標字體的scss文件放在ionicons.scss中,定義字體名稱爲Ionicons

而圖標庫則成爲另一個git項目,相關的類型放在ionicons-icon.scss中。在github中打開源碼文件,ctrl+f搜索heart,能夠看到css是這樣的:

.ion-ios-heart:before { content: "\f443"; }
.ion-ios-heart-outline:before { content: "\f442"; }

經過僞元素,指明瞭對應的圖標字體。-outline後綴指明的是輪廓形狀的圖標。

知道了這些,咱們就能夠自定義字體文件和css類,從而讓ion-icon也支持咱們自定義的圖標了。

準備工做

圖標文件

圖標文件,通常你們都會用illustrator矢量設計軟件設計,而後導出.svg格式的文件。

要打包成字體文件,也有很多工具,經常使用的是阿里出品的 iconfont。具體使用方法,網站上講解的很是清楚,這裏就很少說了。

當你上傳本身的圖標svg文件,導入項目,下載完成後,會獲得一堆文件。
圖標字體文件

有3種方式,可使用圖標:

  • unicode 最原始的方式,可是兼容性好。

  • fontclass 使用僞元素和css類的方式,與ionic同樣,兼容限制ie8+

  • symbol 惟一支持保留顏色的方式,可是兼容性須要考慮(支持svg的設備和瀏覽器能夠)

在例子中,咱們選用fontclass足矣。

部署文件

將生成的字體文件拷貝到ionic項目src目錄下assets中(具體目錄根據項目的要求,這裏只是例子)的fonts目錄裏。

而後,書寫一份.scss文件,內容以下:

@import "ionicons-variables";

$jpicons-font-path: $font-path !default;

@font-face {
  font-family: "jp-icon";
  src: url('#{$jpicons-font-path}/iconfont.eot?t=1493779389504'); /* IE9*/
  src: url('#{$jpicons-font-path}/iconfont.eot?t=1493779389504#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('#{$jpicons-font-path}/iconfont.woff?t=1493779389504') format('woff'), /* chrome, firefox */
  url('#{$jpicons-font-path}/iconfont.ttf?t=1493779389504') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('#{$jpicons-font-path}/iconfont.svg?t=1493779389504#jp-iconfont') format('svg'); /* iOS 4.1- */
}

.jp-icon {
  font-family:"jp-icon" !important;
  font-size:16px;
  font-style:normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

字體名和路徑等等,根據須要自定義就能夠了。

下一步,就能夠定義本身的類名了,因爲例子使用Material Design風格,所以,定義以下:

.ion-md-jpicon__evalTab:before { content: "\e64e"; }

.ion-md-jpicon__recTab:before { content: "\e650"; }

.ion-md-jpicon__storeTab:before { content: "\e651"; }

名字的定義按照以前提到的格式化文本的形式就能夠,這裏因爲想說明清楚的緣由,我把名字定義的略複雜了一點,實際使用中能夠按本身須要修改。

最後別忘了一點,在你的基礎樣式表,好比:app.scss中導入這個scss文件。

@import '../assets/fonts/jpicons.scss';

不管怎樣,當你準備好這些文件時,下一步就可使用本身的圖標字體啦。

使用字體

tabs組件中,能夠很方便的使用定義好的字體:

<ion-tabs class="jp-tabs" >
    <ion-tab tabIcon="jpicon__storeTab" [root]="store" tabTitle="精選推薦" tabUrlPath="store" >
    </ion-tab>
    <ion-tab tabIcon="jpicon__recTab" [root]="recommend" tabTitle="應用場景" tabUrlPath="recommend" >
    </ion-tab>
    <ion-tab tabIcon="jpicon__evalTab" [root]="evaluation" tabTitle="深度評測" tabUrlPath="evaluation" >
    </ion-tab>
</ion-tabs>

在tabs組件的.scss文件中,咱們從新定義在該tabs組件下使用的字體名稱:

.jp-tabs{
   .tab-button{
      &>ion-icon{
        font-family:"jp-icon" !important;   /*指定在當前組件中的ion-icon使用的字體名稱*/
      }
  }
}

此外,若是有定義圖標字體顏色的需求,簡單粗暴的方式是:

.tabs-md .tab-button[aria-selected=true]{
  color:$jp-color;
  .tab-button-icon{
    color:$jp-color;
  }
}

當一個tab被選中時,ionic會修改對應組件元素上的aria-selected,值是true/false

運行ionic serve,查看渲染後的效果:

自定義圖標後的tabs組件

再看html代碼,能夠驗證上面所講到的內容。

使用自定義圖標後的html

總結

若是自定義組件和指令是否是也能夠實現圖標字體的使用?我想是能夠的。

本文只是提供了一種方法而已,不太優雅,可是能夠解決問題。好處是,可使用ionic中的一些關於圖標的功能,例如,在tabs組件中,能夠設置tabLayout屬性來決定圖標和文字的佈局關係,若是要本身開發佈局等功能,固然可行,可是須要花費時間。做爲一種實現,本文的介紹也算做一種方式吧。但做爲研究和推敲原理,我想應該更深刻的發現更好的方式。

我的能力有限,若是有什麼錯漏,請你們批評指正,以後會再補充內容。

相關文章
相關標籤/搜索