最近在使用
ionic3
和Angular
開發一款App。開發體驗仍是挺好的。期間遇到如何在項目中使用自定義圖標字體文件的問題,通過研究,找到了一個解決方法,記錄一下。css
ionic
項目提供了一套豐富的圖標庫,在ionic3中也進行了升級。雖然很實用,可是在實際項目中,仍是須要根據視覺稿來增長圖標。html
一般,咱們都會使用@font-face
導入自定的字體文件。那麼咱們怎麼將這些圖標融入到ionic3的項目中去呢?ios
下面以ionic3
中的tabs
組件做爲例子,提出一種解決方式。git
話說問題是解決了,可是看起來其實並不優雅,不過能解決問題。=.=||github
ionic3
中的圖標組件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
組件:
那麼,ionic是如何根據一個name
屬性,就連接到他的圖標庫中的圖標呢?
因爲ionic3使用了Angular做爲框架開發,所以ion-icon
要麼是組件,要麼是指令。因此咱們看看它的源碼,是如何實現圖標文件的使用的。
源碼傳送門:ion-icon
從源碼中咱們能夠看到,ionic把ion-icon
定義爲一個指令,有三個步驟:
進行平臺風格(ios
、md
)判斷和狀態的判斷。
根據判斷的結果,將輸入的圖標名稱,進一步組合成爲以下形式的格式化文本
ion-{平臺風格標識}-{圖標名}-{修飾}
將上一步獲得的格式文本,添加到元素的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
,查看渲染後的效果:
再看html代碼,能夠驗證上面所講到的內容。
若是自定義組件和指令是否是也能夠實現圖標字體的使用?我想是能夠的。
本文只是提供了一種方法而已,不太優雅,可是能夠解決問題。好處是,可使用ionic中的一些關於圖標的功能,例如,在tabs
組件中,能夠設置tabLayout
屬性來決定圖標和文字的佈局關係,若是要本身開發佈局等功能,固然可行,可是須要花費時間。做爲一種實現,本文的介紹也算做一種方式吧。但做爲研究和推敲原理,我想應該更深刻的發現更好的方式。
我的能力有限,若是有什麼錯漏,請你們批評指正,以後會再補充內容。