由iconfont引起的svg、ttf、woff、woff2图标的研究及其转换

1.背景

其实很早之前便想通过iconfont来实现图标管理和统一(一方面也是为了偷懒,不,是工程化),然而总总原因拖到了现在。

个人感觉iconfont最大的优势有三点
- 矢量图标。相比切图,至少不会糊。
- 可控颜色。相比切图,至少可以换颜色。
- 方便管理和调用。相比切图,至少不会忘。
- 减少请求。所有的图标只用一个请求。

在畅快得使用之后,其原理便引起了我的好奇心…

1.1 iconfont

iconfont官方网址:http://www.iconfont.cn/

阿里妈妈MUX倾力打造的矢量图标管理、交流平台。设计师将图标上传到Iconfont平台,用户可以自定义下载多种格式的icon,平台也可将图标转换为字体,便于前端工程师自由调整与调用。

1.2 icomoon

icomoon官方网址:https://icomoon.io

例子:demo

2 对比

2.1 结果包

我们整理好下载下来的图标结果目录如图所示,
- 其中三个html是三种使用方式的demo,其优势和对比在页面里有具体描述,考虑到语义化和兼容,我使用了fontclass这种形式;
- “iconfont.svg”是图标库的svg格式文件;
- “iconfont.eot”,“iconfont.ttf”,“iconfont.woff”的图标库的字体格式文件;

2.2 svg、eot、ttf、woff比较

注意,这里的SVG指的是svg字体。

2.2.1 介绍

SVG / SVGZ

SVG(Scalable Vector Graphics),即矢量图,是用于描述二维矢量图形的一种图形格式。在 Web 中使用 SVG 可以解决位图放大失真的问题。

TTF / OTF

TTF(TrueTypeFont)是Apple公司和Microsoft公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式。部分的因为这种格式容易被非法复制,因此催生了后来的WOFF字体格式。

EOT

EOT(Embedded Open Type),是微软创造的字体格式。这种格式只在IE6-IE8里使用。

WOFF

WOFF(Web Open Font Format)是一种网页所采用的字体格式标准。此字体格式发展于2009年,现在正由万维网联盟的Web字体工作小组标准化,以求成为推荐标准。此字体格式不但能够有效利用压缩来减少档案大小,并且不包含加密也不受DRM(数位著作权管理)限制。WOFF字体通常比其它字体加载要快,因为使用了OTF和TTF字体里的存储结构和压缩算法。这种字体格式还可以加入元信息和授权信息。

WOFF2(*)

WOFF2(Web Open Font Format 2.0),相比woff最大的优化应该是加强了字体的压缩比。

2.2.2 大小

woff2(*) < woff < ttf ≈ eot < svg

从请求量上来看,woff\woff2格式的图标库最小

2.2.3 兼容

@font-face:

基本全兼容

svgfont:

ios、safari及低端安卓兼容

eot:

只有IE

ttf:

基本兼容,IE兼容情况不是很好

woff:

IE9+,android4.4+,其他兼容良好

woff2(*):

除IE及低系统移动端,其他兼容情况较好

从上图来看
- font-face支持情况良好,完全可以使用字体形式来实现图标;
- PC上兼容较好的是woff格式,ttf对IE的兼容情况不容乐观,svgfont只对Safari兼容,而eot只对IE兼容,如果要做到兼容IE8需要结合eot混着用;
- 移动上eot完全不兼容,svgfont低端系统能很好兼容但不知道为何高端安卓不再支持,考虑到厂里较特殊的兼容要求(ios8.0,android4.0),最为合适的看来就是woff及ttf格式了。

结合大小和兼容情况来看,可以优先使用woff格式(要兼容安卓4.0的话优先使用ttf),如果要兼容IE低版本的话需要使用eot格式,正如iconfont.css的处理:

@font-face {font-family:"iconfont";src:url('iconfont.eot?t=1532589026137'); /* IE9*/src:url('iconfont.eot?t=1532589026137#iefix') format('embedded-opentype'), /* IE6-IE8 */url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAUkAAsAAAAAB4AAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW70ftY21hcAAAAYAAAABcAAABhplABr5nbHlmAAAB3AAAAVgAAAFsZoj2dmhlYWQAAAM0AAAALwAAADYSH23BaGhlYQAAA2QAAAAgAAAAJAfgA4NobXR4AAADhAAAAAwAAAAMC+kAAGxvY2EAAAOQAAAACAAAAAgAdgC2bWF4cAAAA5gAAAAfAAAAIAESAF1uYW1lAAADuAAAAUUAAAJtPlT+fXBvc3QAAAUAAAAAIgAAADPge++EeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/sE4gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxjYm7438AQw9zI0AgUZgTJAQAjlgxweJzFkMENgDAMAy9p6QMxCA8G4sUcnbhrFBPKgwlqybHiWEoUYAGSeIgZ7MJ4cMq18BNr+DkyRWo4tXnv6j9VRLMS6iqFabB5q//You6j01eogzqx+Uv8BlHvC5d4nA2PrU7DUABG73dLu3Zs7e7tf7d1a7vtQoCFtWWIhWEwEAQJCkXwDEcwJIAgQSB4ABAQEhwOh+JNCLwCjhT65Ygjz0dkQv4+pXfJIyZZICOyRfYIgbKEWKdtRCIf0iXYkWy7li6JRESVJB5KG3BjxXLScT5wlYpiQEeILErHYkgF1vIpnSB12oDfDPZ5v8WlO1Q9EV4XO/QJdidpGdOVYnt500q7pnpW49zn/FZVZFmldM7QMXMdTdaqSvEsG4H93lmkHdR8Eewe1LtNfnSTn7T7rgZcXsJsdvWXTRawkvPAMblfadRVL6gnPQtn3/OeWWsPvkg5Wn69mIN0RXpEEKJhEFeg2JYzAbPCMplNsZ6FcFlWCsvS8aCfjaSfIlZdrQhrrD6ze6utU1jGq2HhJRniWGf09w14w4emFtMqN8zioTNedPHIHMBhxSFygXuv2SD/wk87NXicY2BkYGAA4kPBpYHx/DZfGbhZGEDgev2URwj6fz0LI3MjkMvBwAQSBQA9GQs1AHicY2BkYGBu+N/AEMPCwMDw/z8LIwNQBAUwAwBx8QRrBAAAAAPpAAAEAAAAAAAAAAB2ALZ4nGNgZGBgYGYIZGBlAAEmIOYCQgaG/2A+AwAQ9wFwAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgJmRiZGZkYWBsYK1KqO0MpWBAQASpALPAAA=') format('woff'),url('iconfont.ttf?t=1532589026137') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/url('iconfont.svg?t=1532589026137#iconfont') format('svg'); /* iOS 4.1- */
}

3 转换

据美丽大方的UI小姐姐描述,在iconfont平台上要生成一套字体图标,UI所需要上传的是图标的svg文件。那么生成包里的svg图标库的来源就很清晰了——最简单的方式就是把UI上传的svg文件进行处理。那么问题也来了,其余的ttf/eot/woff字体文件是如何生成的呢?

此节转换过程由nodejs实现,只讲实现不知道原理,不感冒的同学可直接跳过~

  • 目录结构:
    ├─dist 生成图标地址
    ├─node_modules
    ├─src 源文件
    │ └─svg
    ├─index.html 测试html
    ├─index.js node脚本
    └─package.json

3.1 转换为svgfont

  • 依赖包:svgicons2svgfont
  • 准备工作:一些svg图标文件

例子

脚本(index.js):

    const join = require('path').join;const fs = require('fs');const SVGIcons2SVGFontStream = require('svgicons2svgfont');const DIST_PATH = join(__dirname, 'dist/iconfont.svg');// initconst fontStream = new SVGIcons2SVGFontStream({fontName: 'iconfont'      // 字体名(font-family)});// 设置导出svgfont文件fontStream.pipe(fs.createWriteStream(DIST_PATH))     // 导出的svgfont文件路径.on('finish', function() {     // 完成console.log(`SvgFont successfully created!(${DIST_PATH})`)}).on('error', function(err) {   // 错误console.log(err);});// add icon1const glyph1 = fs.createReadStream(join(__dirname, 'src/svg/ad-1.svg'));    // svg路径glyph1.metadata = {unicode: ['\uE001'],    // unicodename: 'icon1'                 // icon名};fontStream.write(glyph1);// add icon2const glyph2 = fs.createReadStream(join(__dirname, 'src/svg/add-pluss-1.svg'));glyph2.metadata = {unicode: ['\uE002'],name: 'icon2'};fontStream.write(glyph2);fontStream.end();   // end

执行: node index

可以在dist目录下看到生成的“iconfont.svg”文件

查看svg源码:

使用(index.html):

    <style type="text/css">@font-face {font-family:"iconfont";src:url('dist/iconfont.svg#iconfont') format('svg');}.u-iconfont{display:inline-block;font-family:"iconfont" !important;font-size:26px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}</style><h1>iconfont——svgfont</h1><div><em class="u-iconfont">&#xE001;</em><em class="u-iconfont">&#xE002;</em></div>

页面展示:

3.2 svgfont转ttf

  • 依赖包:svg2ttf
  • 准备工作:svgfont文件

例子

脚本(index.js):

    const fs = require('fs');const join = require('path').join;const svg2ttf = require('svg2ttf');const DIST_PATH = join(__dirname, 'dist/iconfont.ttf');     // 输出地址let ttf = svg2ttf(fs.readFileSync(join(__dirname, 'dist/iconfont.svg'), 'utf8'), {});fs.writeFile(DIST_PATH, new Buffer(ttf.buffer), (err, data) => {if (err) {console.log(err);return false;}console.log(`Ttf icon successfully created!(${DIST_PATH})`)});

使用(index.html):

    <style type="text/css">@font-face {font-family:"iconfont";src:url('dist/iconfont.ttf#iconfont') format('truetype');}.u-iconfont{display:inline-block;font-family:"iconfont" !important;font-size:26px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}</style><h1>iconfont——svgfont</h1><div><em class="u-iconfont">&#xE001;</em><em class="u-iconfont">&#xE002;</em></div>

执行: node index

可以在dist目录下看到生成的“iconfont.ttf”文件

页面展示:

3.3 ttf转eot

  • 依赖包:ttf2eot
  • 准备工作:ttf文件

脚本(index.js):

    const fs = require('fs');const join = require('path').join;const ttf2eot = require('ttf2eot');const DIST_PATH = join(__dirname, 'dist/iconfont.eot');     // 输出地址let ttf = fs.readFileSync(join(__dirname, 'dist/iconfont.ttf'));let eot = new Buffer(ttf2eot(ttf).buffer);fs.writeFile(DIST_PATH, eot, (err, data) => {if (err) {console.log(err);return false;}console.log(`Eot icon successfully created!(${DIST_PATH})`)});

使用(index.html):

    <style type="text/css">@font-face {font-family:"iconfont";src:url('dist/iconfont.eot'); /* IE9*/src:url('dist/iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */}.u-iconfont{display:inline-block;font-family:"iconfont" !important;font-size:26px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}</style><h1>iconfont——eot</h1><div><em class="u-iconfont">&#xE001;</em><em class="u-iconfont">&#xE002;</em></div>

执行: node index

可以在dist目录下看到生成的“iconfont.eot”文件

页面展示(IE):

3.3 ttf转woff

  • 依赖包:ttf2woff
  • 准备工作:ttf文件

脚本(index.js):

    const fs = require('fs');const join = require('path').join;const ttf2woff = require('ttf2woff');const DIST_PATH = join(__dirname, 'dist/iconfont.woff');     // 输出地址let ttf = fs.readFileSync(join(__dirname, 'dist/iconfont.ttf'));let woff = new Buffer(ttf2woff(ttf).buffer);fs.writeFile(DIST_PATH, woff, (err, data) => {if (err) {console.log(err);return false;}console.log(`Woff icon successfully created!(${DIST_PATH})`)});

使用(index.html):

    <style type="text/css">@font-face {font-family:"iconfont";src:url('dist/iconfont.woff#iconfont') format('woff');}.u-iconfont{display:inline-block;font-family:"iconfont" !important;font-size:26px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}</style><h1>iconfont——woff</h1><div><em class="u-iconfont">&#xE001;</em><em class="u-iconfont">&#xE002;</em></div>

执行: node index

可以在dist目录下看到生成的“iconfont.woff”文件

页面展示:

3.4 ttf转WOFF2(*)

  • 依赖包:ttf2woff2
  • 准备工作:ttf文件

脚本(index.js):

    const fs = require('fs');const join = require('path').join;const ttf2woff2 = require('ttf2woff2');const DIST_PATH = join(__dirname, 'dist/iconfont.woff');     // 输出地址let ttf = fs.readFileSync(join(__dirname, 'dist/iconfont.ttf'));let woff2 = new Buffer(ttf2woff2(ttf).buffer);fs.writeFile(DIST_PATH, woff2, (err, data) => {if (err) {console.log(err);return false;}console.log(`Woff2 icon successfully created!(${DIST_PATH})`)});

使用(index.html):

    <style type="text/css">@font-face {font-family:"iconfont";src:url('dist/iconfont.woff2#iconfont') format('woff2');}.u-iconfont{display:inline-block;font-family:"iconfont" !important;font-size:26px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}</style><h1>iconfont——woff2</h1><div><em class="u-iconfont">&#xE001;</em><em class="u-iconfont">&#xE002;</em></div>

执行: node index

可以在dist目录下看到生成的“iconfont.woff2”文件

页面展示:

4 svgs2fonts

结合以上的插件,自己撸了个批量转换的包。——svgs2fonts: svg图标转字体图标库(svgs -> svg,ttf,eot,woff,woff2)。

  • 【github-svgs2fonts】
  • 【npm-svgs2fonts】

原理很简单:

    svgs -> svg font > ttf > eot/woff/woff2

4.1 安装使用

安装:

    npm i -g svgs2fonts

验证:

    svgs2fonts -v

使用:

cmd
svgs2fonts{{srcpath}}{{distpath}}--options
  • srcpath: svg源文件路径(相对当前窗口环境),传”“时为当前窗口路径;
  • distpath: 导出路径,默认在源文件路径下;
nodejs
const svgs2fonts = require('svgs2fonts');const join = require('path').join;svgs2fonts.init({src: __dirname,     // svg pathdist: join(__dirname, 'dest'),  // output pathfontName: 'myIconfont', // font namestartNumber: 20000  // unicode start numbernodemo: true        // no demo html files});

example

    svgs2fonts svg dist

参数

-n / –name

图标库的名字(default: “iconfont”).

example

    svgs2fonts svg dist -n myiconfont
–number

unicode起始编码(default: 10000).

example

    svgs2fonts svg dist --number 50000
–nodemo

不要demo html.

example

    svgs2fonts svg dist --nodemo

生成结果:

  • demo_fontclass.html:使用class展示的demo页面;
  • demo_unicode.html:使用unicode展示的demo页面;

>>文本博客地址
有建议或想砸鸡蛋可 -> michealwayne@163.com


参考资料:

  • 百度百科
  • mdn-svgfont

由iconfont引起的svg、ttf、woff、woff2图标的研究及转换(svgs2fonts)相关推荐

  1. 如何在css文件中使用本地ttf/woff/woff2字体?

    如何在css文件中使用本地ttf/woff/woff2字体? 1.首先下载ttf.woff.woff2字体文件 免费的字体文件可以上阿里矢量图库进行下载,不过数量很少. 2.在css文件中配置相应代码 ...

  2. Maven工程.ttf .woff .woff2读取插件配置

    maven插件配置

  3. 解决Web部署 svg/woff/woff2字体 404错误

    问题:最近在IIS上部署web项目的时候,发现浏览器总是报找不到woff.woff2字体的错误.导致浏览器加载字体报404错误,白白消耗了100-200毫秒的加载时间. 原因:因为服务器IIS不认SV ...

  4. 非常方便的将 SVG 图标生成 TTF/EOT/WOFF/WOFF2/SVG 字体

    一般情况我通过 iconfont 或者 icomoon 来实现图标管理生成字体,导入到项目中使用. ┌────────┐ ┌────────────┐ │iconfont │──┐ │ Project ...

  5. Php在线字体woff转svg,在线字体格式转换ttf/otf/eot/woff/woff2格式工具

    在做网站样式时,我们有时找不到自己需要的字体文件,就需要自己需要自己来制作一个,如何制作了?这里给大家推荐一款自己在用的在线字体转换ttf/otf/eot/woff/woff2格式工具. 这款在线字体 ...

  6. web服务器 字体.svg/.woff/.woff2 404错误 解决方案

    先来看看问题 按理说不应该报404啊,因为我这个路径下面的的确确有这个文件 相信不少开发者都遇到过字体引用的问题,明明路径啥的都没问题,但就是浏览器输出错误信息.引起类似以上问题的原因是由于Web服务 ...

  7. 阿里iconfont上传svg图片空白、或展示不全的解决方案/搜索到的icon无法改变颜色解决方案

    问题1:阿里iconfont上传svg图片空白.或展示不全 原因 造成这个问题的原因,可能是因为sketch.dx等软件在导出svg时,自动在svg上添加了一些iconfont平台无法解析的属性造成的 ...

  8. 使用 iconfont 中的 svg 图标

    最近在使用 Element-UI开发的时候发现其图标并不是够用,于是想着如何将 https://www.iconfont.cn/home/index 上面的图标导入进自己的项目中去. 网上的搜索结果基 ...

  9. 将svg编译成字体图标

    有时将svg图标编译成字体图标,可以更方便的来使用,下面就介绍如何将svg编译成字体图标 1. 使用npm安装svgtofont npm i svgtofont 2. 编译字体图标 const svg ...

  10. 将svg文件化成字体图标的步骤

     一 前提摘要     有一个活就是按照需求在现有的项目中新增几个项目和修改几个项目,是很简单的,但当中遇到了一个小问题,就是tabs中图标选中和被选中的颜色问题,如果是新开发的,目前掌握的有两种办法 ...

最新文章

  1. 用ExayX在VS2019上输出文本有误的解决方案
  2. sqlserver2008数据库自动备份的sql脚本及使用bat命令执行脚本
  3. 用Java读取xml文件内容
  4. STL中的set/map
  5. python seaborn heatmap可视化相关性矩阵
  6. dict过滤 python_小猿圈解析Python开发的技巧都有哪些?
  7. 6 linux 制作raw命令_云计算网络知识学习-linux网络基础
  8. 抖音上热门的好处有哪些?
  9. c++小游戏——打飞机
  10. Foxmail是什么邮箱?
  11. NMOS 与 PMOS
  12. 217小白最新详细linux环境下安装博客WordPress教程
  13. Java模拟登录强智教务系统分析思路
  14. 论文阅读:Regularizing Deep Networks with Semantic Data Augmentation
  15. Web前端开发常用的开发工具
  16. ruok is not executed because it is not in the whitelist.
  17. 甲骨文献相关资料持续分享
  18. 多项式(Polynomial)的运算——利用单链表
  19. 从校园到职场 - 再谈切忌照本宣科
  20. 将15位数字转换成人民币金额

热门文章

  1. SBC在企业IP通信系统中的应用
  2. 用CSS3画出一个正方体
  3. 女子人身安全防卫指南
  4. 区块链与程序员:赚钱还是创业
  5. PowerDesigner实用技巧小结
  6. 解决1KB文件夹快捷方式病毒
  7. 有妇如此,夫复何求!
  8. 文献整理和论文阅读方法
  9. Lession 9-10 Cell Phone Taboos
  10. 系统win8 任务栏消失不见的解决办法