Icon 進化史

2022-01-10 西廠XUX

「南方古猿」之 png sprite

看到上面這張圖,相信好多資深前端會感到很親切。

早期為了減少資源的請求,人們想到了將小的 png 圖片合併到一張圖上,然後根據 background-position   來顯示不同的圖片。

早期還有靠人肉來測量坐標,隨著構建工具的發展,我們可以用一些插件,如 grunt-spritesmith ( https://github.com/Ensighten/grunt-spritesmith )、gulp.spritesmith ( https://github.com/twolfson/gulp.spritesmith ) 等。它可以幫助我們自動合成,並生成好 css, 位置都計算好的。

那麼使用 png 圖片這種方式它的優點就是兼容性好。但是一旦開發多了,它的不便變體現出來了,換顏色、改大小、透明度、多倍屏等等。

所以對於這種方式我們只能緬懷。

「能人」之 Iconfont

於是人們又想出了用字體文件取代圖片文件:Iconfont。

雖然早期製作或尋找合適字體比較麻煩,但隨著各種字體庫的網站出現,如: http://www.iconfont.cn ,那都不是事了。再加上 css 的自定義字體的兼容性非常好,Iconfont 迅速開始流行起來。以這個站為例,大概看下使用方法:

在 Iconfont 中創建自己的項目,將需要使用的圖標添加到自己的項目中。

複製出 Unicode 或 Font class

全部代碼如下


這裡有demo:https://codepen.io/maming/pen/YNpMwd

在實際開發中,我們會把常用的一些圖標封裝成組件 ( http://uxcore.coding.me/css/iconfont/ ),直接使用。像這樣


Iconfont 用起來挺方便的,而且兼容性也十分的好,大小、顏色可隨意改變。

但它仍有缺陷:

字體需要加載資源

有時候可能會出現鋸齒

只能被渲染成單色或者css3的漸變色

所以我們要繼續進化。

「直立人」之 svg symbol

使用 svg ,這裡所謂的進化並不是 svg 本身的進化,因為 svg 並不晚於 Iconfont。只是環境(兼容性)的原因導致它無用武之地。就像最近火的一塌糊塗的 AI, 其實最早在 1956 年就提出了。隨著外界因素的進化,IE6/7/8 的淘汰, android 4.x 的開始,svg 的機會變到來了。先看下兼容性:

The <symbol> element is used to define graphical template objects which can be instantiated by a <use> element.

通過定義的 svg 模板,我們可以使用來加載它。

那麼是怎麼來的呢?

同樣,在這個構建工具十分發達的時刻。
最開始我們使用了 gulp-svg-symbols ( https://github.com/Hiswe/gulp-svg-symbols ),它可以將指定目錄中的 svg 自動合併到一個 svg 文件中,文件裡包括了所有 icon 的 symbol 模板,然後再將這個模板將其隱藏放到 index.html 中。

但是這個庫有個坑點是它依賴了一個 Unicode 的包,這個包在國內安裝炒雞慢,於是我們棄用了它,使用了gulp-svgstore ( https://github.com/w0rm/gulp-svgstore )

按照這種方式我們成功的開發一 salt-icon ( https://github.com/saltjs/salt-ui/blob/master/demo/src/pages/icon/PageIcon.js ) 這個組件,裡面包括了一些常用的 icon。使用方式:


這樣我們在 mobile 端用 svg 替代了 Iconfont,解決了上述 Iconfont 提到的問題。

但是很快我們就發現,在 index.html 中引入那一坨 symbol 模板是極其噁心的。

隨著 webpack ( https://webpack.github.io/ ) 打包的成熟,各種 loader,我們將那一坨 symbol 模板直接打包成一個 salt-icon-source.js 文件,在這個文件中將其 append 到 body 上。

同時發現了上述提到的 iconfont 網站 ( http://www.iconfont.cn/ ) 也支持直接導出 symbol 文件。


這樣雖然解決了引入模板的那個問題,但是後面又發現的 symbol 在安卓 4.3.x 下無法顯示,也就是說 symbol 的兼容性並沒有直接使用 svg 好。

然後我們通過使用一個叫 svg4everybody ( https://github.com/jonathantneal/svg4everybody ) 的庫,解決了上述兼容性問題。(它的原理是如果發現不支持 symbol 的,它會通過 xlink:href 拿到 svg 的資源,然後動態創建一個 svg,插入到當前位置)

雖然解決了兼容性的問題,但是我們深深的感覺到了這種方式的不優雅。

講的這裡,可能會有人會有疑問,既然已經有 svg-react-loader ( https://github.com/jhamlet/svg-react-loader ) 了,為什麼不直接 import svg 文件?

業務中使用的圖片當然可以直接 import 加載,但一些通過的圖標我們希望是能統一起來,做出組件,更方便的使用。

而且我們組件中還會對 svg 處理了它事件不能冒泡的問題,也就是在某些低版本的安卓機上,svg 圖標是無法點擊的。解決方案有兩種:

不過,這個問題可以給我帶來啟示,『既然已經有 svg-react-loader ( https://github.com/jhamlet/svg-react-loader ) 了』,那麼 svg-loader 裡做了什麼呢?symbol 的方式或許真的可以淘汰了。

「智人」之 svg

看下 svg-react-loader ( https://github.com/jhamlet/svg-react-loader ) 的實現
首先有一個模板

然後有一個 sanitize.js ,會對 svg 做一些處理,加上標準的 xml namespace, 把 React 特有的屬性 class / for 轉化為 className / htmlFor, 把屬性名轉化為駝峰。

最後根據模板生成這樣一段代碼

這樣的代碼我們就可以直接在 react 中直接使用了。

所以我們的組件藉助這樣的思想,完全棄用了 symbol 模式。

我們先掃描對應的 svg 文件,將其按上面的思路生成一個個單獨的 js 文件。
在組件層面可以再封裝一層,統一引入,提供一個通用的調用方式,和上面一樣。

更好的是你也可以單獨引用每一個文件,減小使用體積。

最後我們憧憬一下,隨著 react 15.x 的發布,react 對 svg 的支持越來越好了,隨著 IE 8 也即將被遺棄,我們的 PC 端也有望從 Iconfont 轉換到 svg 了。


相關焦點

  • 一個人的「手機進化史」
    12月初,一款名為「手機進化史」的小程序引起了不小的化學反應,除了朋友圈之外,諸多社交網絡均看到了人們對「舊物」手機的懷念。懷念方式也很簡單,小程序幫你梳理曾用過哪些手機,並生成精美長圖。量子程序請到了「手機進化史」背後的獨立開發者ruff,和他聊了聊產品設計和對「舊物」的懷念之情。
  • NS遊戲推薦:可以玩的RPG遊戲進化史--《進化之地》
    《進化之地1》可以說是致敬了塞爾達、重裝機兵、最終幻想以及其他開創了新時代RPG遊戲:就塞爾達而言,比如,拾取物品並舉高高,然後聽到愉快的提示音;男主名叫克林科,提著劍四處砍草;飛來飛去的蝙蝠、能在陸地上遊走的八爪魚以及只能從側面攻擊的裝甲兵和骷髏,等等。
  • 《龍珠》遊戲進化史
    最近國外的著名視頻博主「進化の軌跡チャンネル」上傳了一段《龍珠》歷代遊戲進化史,裡面從前往後,詳細梳理了各代龍珠的實際遊戲畫面。有興趣的朋友可以欣賞一番,感受一下龍珠遊戲的變遷。
  • 人類進化史不完整,有很多缺失環節?
    ‍        「人類的演化缺失一個過渡態」其實很狡猾,因為這個謠言很容易讓人誤解成進化是直線現象,而完全無視演化分支。進化是樹狀的。擁有很多的枝條。神創論者經常叫喧著缺失環節,實際上就是想讓你把人類進化史當成這樣一個模式:        比如神創論者最喜歡造謠南猿和直立人缺少一個過渡態,其實他們完全無視能人,甚至很少提及(大家別忘了神創論科學的精髓,對聖經不利的證據,就仿佛章魚怪物一樣,趕快躲避無視掉)……而能人是個很關鍵的轉折點。        這種直線進化完全是錯誤的。
  • 一部遊戲追憶RPG這20年:《Evoland》進化之地,一部遊戲進化史
    而《Evoland》進化之地這款遊戲,就完美的致敬了過去20年中優秀的RPG作品,將他們融合在進化之地中,把《進化之地》做成了RPG遊戲發展史。左邊進化之地,右邊塞爾達系列左邊進化之地,右邊《勇者鬥惡龍》系列
  • 摩託羅拉Logo進化史
    下面我們一起來追溯這個已經年近九旬的老品牌logo的進化史:
  • 這款 RPG 又是一部遊戲進化史
    持著「遊戲進化史」這柄大師之劍,進化之地在剛推出時便憑藉著它新鮮的玩法收割了無數粉絲。前幾年帶著更加豐富的機制在 PC 上推出了續作進化之地 2,而現在總算是等來了它的移動端版本。▎隨劇情迭代升級的畫面一代的劇情過於簡單,導致我更多時候是為了進化遊戲而繼續探索。而進化之地 2 準備了一個更加完整的劇情,主角為了拯救大陸,要進行時空穿梭尋找時間之石。
  • Chinajoy·Showgirl進化史
    一起來看看Showgirl的12年進化史。從2004年1月開辦,至今已經辦了十二屆。在前面幾屆Chinajoy上,Showgirl關注度不高,主要是以遊戲展為主。
  • 4分鐘看完《馬裡奧賽車》系列進化史
    4月28日,任天堂NS上的另一個超大作《馬裡奧賽車8豪華版》就要發售了,我們今天搬運了一部Youtube的UP主「進化の軌跡チャンネル」之前製作過一部4分鐘的視頻,該視頻用遊戲畫面直觀地展示了系列9部作品25年來的進化歷程。
  • 奇舞周刊第 261 期:JavaScript 中的 Linter 進化史
    JS Linter 進化史本文主要介紹下 JS Linter 進化史中的三個裡程碑式的工具:JSLint、JSHint 和 ESLint。網際網路企業數據安全體系建設全球的趨勢是越來越重視隱私,在安全領域中,數據安全這個子領域也重新被提到了一個新的高度,本文作者要講的正是數據安全建設。
  • 一部Latitude 編年史,就是半部商用筆記本的進化史
    歷史,充滿著偶然性,但生物和社會進化,卻存在著必然性。儘管筆記本電腦誕生於1985年,但其在商用領域的普及步伐,還是在90年代中期才開始。商用筆記本誕生的標誌性事件,包含了屏幕的TFT彩色化、重量體積上的便攜化,以及鋰電池的採用讓續航時間實用化。
  • 手摸手,帶你優雅的使用 icon
    首先來說說寫這篇文章的主要初衷是:在做前端後臺項目的時候經常會用到很多 icon 圖標,剛開始還好,但隨著項目的不斷迭代,每次修改添加圖標會變得很麻煩,而且總覺得不夠優雅,就開始琢磨著有啥簡單方便的工作流呢?演進史首先我們來說一下前端 icon 的發展史。遠古時代在我剛開始實習時,大部分圖標都是用 img 來實現的。
  • 人類進化史
    約6500萬年前,一顆寬度約16千米的大型隕石撞擊到了今天墨西哥的尤卡坦半島上,造成巨大災難,當時地球上包括恐龍在內的三分之二的動物物種消亡滅絕,爬行動物的黃金時代結束,原始哺乳類動物逃過劫難經過漫長歲月存活下來,之後進化,進行了一個長期的演變過程。
  • 宏基因組測序揭示人腸道微生物的進化史
    樣品來源:糞便相關產品:宏基因組 測序平臺:Illumina GAIIx2研究背景人體腸道微生物組又稱人體的第二基因組,對人體腸道微生物測序研究,可以在微生物功能上更好的理解宿主的進化及個體的發育然而國際上還沒有開展關於狩獵採集人群的腸道微生物基因組的研究,對於狩獵採集人群的腸道微生物的研究,可以很好的展現人腸道微生物的進化史。
  • 【懷舊】QQ網名的進化史
    接下來,我們一起來看看網名的進化史!那個時代網絡上還沒有網紅,全天下的女人的老公還不是宋仲基! 那個時代董小姐還是坐在自行車後面白衣飄飄美少女!那個時候流行歌曲還是「高曉松版」的校園民謠,周星星的無釐頭開始成為一種文化癥結。那個時候上網還是一件稀罕事,網費一個小時多少錢,你咋不上天呢?那個時候在學校上網還得帶塑膠袋腳套!
  • 你不知道的USB的進化史
    EyeOpener今日話題,USB進化史USB的功能有一:傳輸數據,比如拷貝小電影到u盤;二:電源的管理分配,比如讓你的小檯燈,小風扇,發亮發風;三:連接電腦系統與外部設備,比如連接有線滑鼠,鍵盤。
  • Mega進化系統來襲!
    【新增】Mega進化系統              35級開啟Mega進化功能
  • 爬蟲動物進化史
    羊膜卵的出現使它們擺脫了對水的依賴,這是脊椎動物進化史上的一個裡程碑。羊膜卵的特點是在胚胎發育過程中,發生三層胚膜包圍胚胎:外層稱絨毛膜,內層稱羊膜,另有尿囊膜。羊膜腔中充滿著液體,稱羊水,胚胎浸在羊水中,正是藉助於這種自身形成的水環境,它們才不再依賴外界的水環境。
  • 《icon》| 第一章:icon 初現
    全文字數:1216字閱讀時間:4分鐘本文首發于吉利汽車微信公眾號,科幻世界SFW微信公眾號同步轉載icon一個蠶繭般乳白色的艙體原型,像是用3D列印出來的,在這工業化車間的角落顯得格格不入,上面用亮藍色的漆手寫著幾個字母——「icon」,這是什麼意思,尹光華琢磨著,像是一個自指邏輯的玩笑,如同勒內·馬格裡特1964年的超現實主義名畫《這不是一個蘋果》,可這確實是一個icon,什麼的icon?無所謂了,至少它看上去足夠結實。
  • Linux桌面進化史
    作為從 1993 年就開始使用 Linux 的資深用戶,FreeDOS 創始人 Jim Hall 從初代窗口管理器開始,仔細梳理了一遍 Linux 桌面的進化史——X 和窗口管理器Linux 上的第一個「桌面」是在 X Window 系統上運行的窗口管理器。X 為圖形用戶界面提供了基本構建塊,例如在屏幕上創建窗口並提供鍵盤和滑鼠輸入。