一個交互比較多的UI圖里面可能會有很多小圖標,一般可用sprites圖將多個小圖標弄成一張大圖,或者其它的辦法,各種方法的比較可參見博主的另外一篇博客使用css3新屬性clip-path制作小圖標,本文深入討論使用icon-font的的制作方法:在PS里面導出svg,制作字體圖標。這種方法既有sprites圖不需要瀏覽器發多次請求的優點,也有使用clip-path/svg矢量無損的優點,並且支持IE6及以上。
使用sprites圖可以自行用PS將多個小圖標放至一張圖:
sprites圖的缺點是不是矢量的,在適配布局里,在伸縮時可能會失真。而使用icon fonts是矢量放大無損的。
接下來介紹制作icon fonts的方法。
1. 需要安裝PS、AI
2. 下載一個PS的腳本:PSD to SVG,按照里面說明的辦法,將腳本放到PS的腳本目錄:Adobe Photoshop/presets/scripts,重啟PS。
3. 將圖層里面的icon形狀圖層復制到一個新文檔,並將圖層重命名為.svg后綴結尾。弄成svg結尾主要是為了腳本識別哪些圖層要進行轉換。注意圖層命名最好用字母數字和下划線,不然可能會出問題。
4. 執行文件->腳本->PSD to SVG腳本,可能會提示沒有保存文檔,所以執行前先把新建的圖層保存為一個文件。
6. 執行完腳本后會在psd所在的目錄生成兩個文件,一個svg和一個ai
7. 用AI打開生成的ai文件,發現只有左下角有一個點顯示出來了,如下圖左顯示,當把鼠標放上去的時候發現那些path是存在的,只是沒顯示出來。
8. 所以在AI里面把它填充一下,把顯示出來的部份填充成黑色,然后另存為svg:File->script->saveDocs as Svg
9. 接下來,借助icomoon,制作字體。打開icommon(如果打不開,得使用代理因為這網站使用了谷歌的一些服務),點擊右上角的Import Icon按鈕,導入上面保存的svg文件。
icomoon就會跳到select頁面,選中剛剛導入的圖標:
再點擊右下角的Generate Font:
跳到了生成好的icon頁面,點擊get code:
觀察它的使用代碼,發現這個圖標被拆成了6個span表示6個path,還要調節它們的間距。這不是想要的結果,理想的結果應該是只要一個span表示這個圖標就好了。
根據icomoon的給出的提示:
To avoid multicolor glyphs, reimport your SVG after changing all its colors to the same color.
發現是由於各個部份的顏色不一致導致的,上面設置沒有顯示出來的其它5個部份和已經顯示出來左下角那個點的顏色不一致,於是把它們調成一樣的。
這里使用Inkscape進行編輯,因為Inkscape可以直接編輯svg源代碼,更加直觀,打開用PS生成的還沒改過的svg文件:
可以看到,之所以會沒顯示出來,是因為fill屬性設置成了none,所以把它們都改成和左下角那個都一樣的顏色:
保存后上傳到icomoon,再點get code,生成的字體就是完整的一個實體了:
下載后打開,生成的字體文件放在了fonts目錄下,同時icomoon提供了demo,使用時,通過一個@font-face導入字體文件:
@font-face { font-family: 'icomoon'; src:url('fonts/icomoon.eot?3hb5tb'); src:url('fonts/icomoon.eot?3hb5tb#iefix') format('embedded-opentype'), /*為了支持低版本的IE*/ url('fonts/icomoon.ttf?3hb5tb') format('truetype'), url('fonts/icomoon.woff?3hb5tb') format('woff'), url('fonts/icomoon.svg?3hb5tb#icomoon') format('svg'); font-weight: normal; font-style: normal; }
或者在html文件里面用實體代碼吧,例如上面的菜單按鈕是:
<span style="font-family:icommon"></span>
當然也可以用icommon提供的大量免費的圖標和搜索功能,但是使用這些圖標的缺點是大小可能是不一致的,導致在UI里面原本相同大小的字體圖標需要設置不同的的字體大小。而使用UI圖制作的svg大小比例就會貼近UI圖,無需設置多個font-size。
需要注意的是,如果以后還要再導入新的圖標,需要在原先的基礎上添加,icommon支持導入project,將上面的下載的包里面的selection.json導入即可。如果把之前的icon和新的icon再導入一次,會導致之前的icon的編碼發生變化。
上面使用了用AI/linscape的方法修正PS導出的ai/svg文件,也可以直接用文本編輯器修改svg文件。
有的時候,可能需要手動調整下svg的結構,例如上面的搜索框,在PS里面設計師是畫了兩個圓和一條線,如下面所示:
<svg version="1.1" width="40.004px" height="40.004px" viewBox="0 0 40.004 40.004" style="enable-background:new 0 0 40.004 40.004;" xml:space="preserve"> <!-- 外面的圓 --> <path style="fill-rule:evenodd;clip-rule:evenodd;fill:#505050;" d="M19,0c10.493,0,19,8.507,19,19s-8.507,19-19,19S0,29.493,0,19 S8.507,0,19,0z"/> <!-- 里面的圓 --> <path style="fill-rule:evenodd;clip-rule:evenodd;fill:#505050;" d="M19,2c9.389,0,17,7.611,17,17s-7.611,17-17,17S2,28.389,2,19 S9.611,2,19,2z"/> <!-- 放大鏡的手柄 --> <path style="fill-rule:evenodd;clip-rule:evenodd;fill:#505050;" d="M32.691,31.287l7.022,7.022c0.388,0.388,0.388,1.017,0,1.404 s-1.017,0.388-1.404,0l-7.022-7.022c-0.388-0.388-0.388-1.016,0-1.404C31.674,30.899,32.303,30.899,32.691,31.287z"/> </svg>
如果兩個圓的fill顏色都設置成一樣的灰色的話,那么生成的文件是這樣的:
里面那個圓的fill屬性的作用導致放大鏡中間被填充了,因此需要手動改一下,將兩個圓放到同一個path,這樣圍起來的路徑就是一個環:
<svg width="40.004px" height="40.004px" viewBox="0 0 40.004 40.004" style="enable-background:new 0 0 40.004 40.004;" xml:space="preserve"> <!-- 把兩個圓放到一起形成一條封閉的路徑,即一個環 --> <path style="fill-rule:evenodd;clip-rule:evenodd;fill:#505050;" d="M19,0c10.493,0,19,8.507,19,19s-8.507,19-19,19S0,29.493,0,19 S8.507,0,19,0 M19,2c9.389,0,17,7.611,17,17s-7.611,17-17,17S2,28.389,2,19 S9.611,2,19,2z"/> <!-- 放大鏡的手柄 --> <path style="fill-rule:evenodd;clip-rule:evenodd;fill:#505050;" d="M32.691,31.287l7.022,7.022c0.388,0.388,0.388,1.017,0,1.404 s-1.017,0.388-1.404,0l-7.022-7.022c-0.388-0.388-0.388-1.016,0-1.404C31.674,30.899,32.303,30.899,32.691,31.287z"/> </svg>
生成的放大鏡就正常了:
還有的圖標可能是由多個圖層組成的,這個時候需要分別生成svg,然后放到一起,用Inkscape或ai調下相對位置。這里需要點svg的知識,可以參考MDN上的svg教程。
后來發現,其實不用這么麻煩,PS有一個合並形狀的功能,如果一個圖標是兩個圖層的,可以先合並為一個形狀,選中兩個圖層,然后右鍵“合並形狀”:
合並完了之后,再合並形狀組件,先選中左邊工具欄矩形工具,再點上面的“合並組件”,這樣就所有的路徑都會合成一個path。然后再使用上面說的生成字體圖標的方法。通過這樣的處理就不會出現上面的問題了,基本上百試百靈,不管多復雜的圖標都適用。
最后再比較下大小,把上面第一張sprites圖里面的9個小圖標都制作成icon fonts,生成的文件大小為:
最大的為6.6KB,小的為2.6KB,而上面生成的sprites圖為7.1KB,用tinypng壓縮后為3.0KB。可以看到,如果只有幾個圖標並且圖標本身就比較小時,在文件大小上,icon-font比sprites圖的優勢並不明顯。當圖標增加到18個,即把上面的圖標再導入一次,現制作的icon-fonts大小為:
18個icon-font的最大svg格式的為13kb,最小的為4.1KB,sprites圖為6KB,考慮到svg格式的並不太會可能被瀏覽器下載, 如下圖所示。所以在文件大小上,icon-fonts還是比sprites圖有優勢的,如果圖標個數不多的話差別不大。如果圖標需要展示得很大的話,icon fonts的優勢就很明顯了。
IE6 | 僅支持 Embedded OpenType(.eot) 格式。 |
---|---|
IE7 | 僅支持 Embedded OpenType(.eot) 格式。 |
IE8 | 僅支持 Embedded OpenType(.eot) 格式。 |
Firefox 3.5 | 支持 TrueType、OpenType(.ttf, .otf) 格式。 |
Firefox 3.6 | 支持 TrueType、OpenType(.ttf, .otf) 及 WOFF 格式。 |
Chrome | 支持 TrueType、OpenType(.ttf, .otf) 及 SVG Font(.svg) 格式。 |
Safari | 支持 TrueType、OpenType(.ttf, .otf) 及 SVG Font(.svg) 格式。 |
Opera | 支持 TrueType、OpenType(.ttf, .otf) 及 SVG Font(.svg) 格式。 |
來自w3 help
使用sprites圖的另外一個缺點是,在移動端低配置的設備,可能會給內存和CPU帶來很大的壓力,如果sprites圖太大的話。而icon font的最大優點是矢量無損,缺點是只能支持單色的圖標,因為它是一個普通的字體,還有在制作上稍麻煩。
參考:
2. icomoon,制作icon font的在線工具
3. PSD to SVG