iconfont技术分享

主宰稳场 提交于 2020-01-27 13:04:46

提问

  • 提需求的人图标样式(颜色)要换?
  • 图标如何满足不同的分辨率以及清晰度?
  • 图标太多导致项目体积越来越大,如何瘦身?
  • 按钮状态切换只用一个图标,例如点击和松开,甚至更多的状态?

用字体来代替图标 阿里iconfont

  • 轻量性:一个图标字体比一系列的图像(特别是在Retina屏中使用双倍图像)要小。一旦图标字体加载了,图标就会马上渲染出来,不需要下载一个图像。可以减少HTTP请求,还可以配合HTML5离线存储做性能优化。

  • 灵活性:图标字体可以用过font-size属性设置其任何大小,还可以加各种文字效果,包括颜色、Hover状态、透明度、阴影和翻转等效果。可以在任何背景下显示。使用位图的话,必须得为每个不同大小和不同效果的图像输出一个不同文件。

  • 跨平台:支持android,iOS,web,微信小程序。

  • 兼容性:网页字体支持所有现代浏览器,包括IE低版本。

iconfont 制作的基本原理

Unicode 码表是一个很大的表格,每个表格都对应一个 Unicode 字符,每个字符都有一个 Unicode 码值对应,如 “李” 对应 “\u674e”, “靖” 对应 “\u9756”。因为码表很大,有部分表格并没有对应的字符,但是它有自己的码值。iconfont 的制作,首先将绘制的图形(可以是一张图片、也可以是一个 svg 描述)通过工具或者程序生成文字icon,然后将文字icon对应到码表之中,为了不干预码表中已有的字符,我们通常会把文字icon对应到没有字符的表格中,最后导出我们额外对应的表格信息,生成iconfont。如下图所示:

                              Unicode 码表
                           +-----------------+
           ...             |     |     |     |
                           |     |     |     |
   图形icon     文字icon    +-----------------+
  +-------+    +------+    |     |     |     |
  |icon a +---->   A  +-----------> Ua |     |
  +-------+    +------+    |     |     |     |
                           +-----------------+
  +-------+    +------+    |     |     |     |
  |icon b +---->   B  +-----> Ub +     |     +------> iconfont
  +-------+    +------+    |     |     |     |
                           +-----------------+
  +-------+    +------+    |     |     |     |
  |icon C +---->   C  +-----> Uc |     |     |
  +-------+    +------+    |     |     |     |
                           +-----------------+
           ...             |     |     |     |
                           |     |     |     |
                           +-----------------+

图中,三个icon分别对应到 Unicode 码表中码值为 Ua Ub Uc 的三个表格,那么最后导出的 iconfont 也就只包含这三个字符信息,这个体积是很小的。

SVG

一种xml格式的字体数据,每个字的图形对应了一个路径。这个路径就是我们svg里面的path对应的序列。

[图片上传失败…(image-7204df-1579312307888)]

好了于是我们有了一个全新的思路,由设计师上传svg,我们存储下来,然后大家自由组合,由平台拼出对应的svg字体,然后再转换到不同的其他格式的字体。

[图片上传失败…(image-9d0b45-1579312307888)]

使用注意要点

  • 字体使用unicode码去引用,容易散落各地,应该统一写在配置文件中通过变量访问
  • iOS oc和swift表示方式不同
/** oc **/
#define ICON_ZHI_SHU @"\U0000e619"
/** swift **/
static let ICON_JING_XUAN:String = "\u{0000e601}";
  • android需要通过代码修改Typeface来使用iconfont字体,可自己创建个TextView类初始化的时候添加好字体,方便layout.xml中使用
      
    public IconTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        changeTypeFace(context,attrs);
    }

    private void changeTypeFace(Context context, AttributeSet attrs)
    {
        if (attrs != null)
        {
            Typeface mtf = Typeface.createFromAsset(context.getAssets(),
                    iconPath);
            super.setTypeface(mtf);
        }
    }
  • 微信小程序无法使用外部字体,需要字体通过base64编码后的字符串引入

缺点

  • 图标字体只能被渲染成单色或者CSS3的渐变色,由于此限制使得它不能广泛使用。

  • 使用版权上有限制,有好多字体是收费的。当然也有很多免费开源的精美字体图标供下载使用。

  • 创作自已的字体图标很费时间,重构人员后期维护的成本偏高

  • 开发app的情况下仅限于本地icon显示,远程图标仍然只能使用图片的形式。

自动化创建资源配置类

下载示例工程文件,找到translate.sh脚本
image

执行脚本,生成的.h或者.swift直接在iOS工程项目中导入使用,生成的strings.xml导入到android项目中

#创建IconFontConfig.h
./translate.sh objc

#创建IconFontConfig.swift
./translate.sh swift

#创建strings.xml
./translate.sh java

为了避免android项目中默认strings.xml中已经配置资源,和现有的资源文件冲突,建议在项目中另外创建一个资源文件夹存放iconfont生成的strings.xml资源描述

android {
    compileSdkVersion 26
    defaultConfig {
		......
    }
    buildTypes {
		......
    }
    sourceSets {
        main {
            res.srcDirs "src/main/res-icon"
        }
    }
}

这样iconfont生成的strings.xml可以存放在该目录下互不冲突
image

image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!