新建图标项目

  1. 首先在 阿里巴巴矢量图标库 需要有自己的项目并往其中添加图标

  2. 在项目设置可以直接打开彩色设置

    image-20221030155825486

    image-20221030155846666

引入图标

unicode 是字体在网页端最原始的应用方式,但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。

可以采用 fontclass 的引用方式即可使用多彩图标。但是单一项目彩色图标上限是 40 个图标,如果对图标有大量需求而又不想引入过多 css 链接的,则 symbol 依然是最优解。

  1. 找到之前新建的图标项目,查看在线链接,获取 Symbol.js 的在线链接,在主题配置文件的 inject 配置项中填入:

    1
    2
    3
    inject:
    bottom:
    + - <script async src="//at.alicdn.com/t/c/font_3738170_ttfc0lykul.js"></script>

    此处 async 是异步加载属性,能够减少 HTML 阻塞。

  2. 打开 [Blogroot]\themes\butterfly\source\css\custom.css, 输入以下内容:

    1
    2
    3
    4
    5
    6
    7
    svg.icon {
    width: 1.2em; height: 1.2em;
    /* width和height定义图标的默认宽度和高度*/
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
    }

    当然同样得在主题配置文件的 inject 引入 custom.css

    必须清除浏览器缓存,才能看到正常大小图标。

  3. 添加外挂标签,在 [Blogroot]\themes\butterfly\scripts\tag\ 目录下新建 iconfont.js,输入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    'use strict';

    function iconFont(args) {
    args = args.join(' ').split(',')
    let p0 = args[0]
    let p1 = args[1]?args[1]:1
    return `<svg class="icon" style="width:${p1}em; height:${p1}em" aria-hidden="true"><use xlink:href="#${p0}"></use></svg>`;
    }

    hexo.extend.tag.register('icon',iconFont);
  4. 以后即可使用外挂标签的形式来写入图标了

    语法示例:

    1
    {% icon [icon-xxxx],[font-size] %}
    1. icon-xxxx:表示图标font-class,可以在自己的阿里矢量图标库项目的font-class引用方案内查询并复制。
    2. font-size:表示图标大小,直接填写数字即可,单位为em。图标大小默认值为1em

    示例源码:

    1
    {% icon icon-email,3 %}

    image-20221030171052868

顶部菜单图标

将菜单栏改成iconfont图标,只能使用fontclass引入方案配合自定义css来实现单一彩色图标。而无法使用symbol引入方案。这是因为symbol引入方案和fontclass引入方案是基于不同原理,前者实质是一个svg,而后者实质是一个字体。为了能够实现symbol引入,毫无疑问是需要改动源码的。

  1. 通过二重判断,可以同时兼容fontawesome写法和iconfontsymbol写法,但是因为判断基准是基于开头是fa还是icon,所以若要使用iconfontfontclass写法,就需要写成fa icon-xxx了。
  2. 因为butterfly_v3.7.0改动了menu_item.pug的基本结构,所以不兼容低于Butterfly_v3.7.0的主题版本。
  1. 修改[Blogroot]\themes\butterfly\layout\includes\header\menu_item.pug

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    if theme.menu
    .menus_items
    each value, label in theme.menu
    if typeof value !== 'object'
    .menus_item
    - const valueArray = value.split('||')
    - a.site-page(href=url_for(trim(valueArray[0])))
    + a.site-page.faa-parent.animated-hover(href=url_for(trim(valueArray[0])))
    if valueArray[1]
    - i.fa-fw(class=trim(valueArray[1]))
    + - var icon_value = trim(valueArray[1])
    + - var anima_value = valueArray[2] ? trim(valueArray[2]) : 'faa-tada'
    + if icon_value.substring(0,2)=="fa"
    + i.fa-fw(class=icon_value + ' ' + anima_value)
    + else if icon_value.substring(0,4)=="icon"
    + svg.icon(aria-hidden="true" class=anima_value)
    + use(xlink:href=`#`+ icon_value)
    span=' '+label
    else
    .menus_item
    - const labelArray = label.split('||')
    - const hideClass = labelArray[2] && trim(labelArray[2]) === 'hide' ? 'hide' : ''
    - a.site-page.group(class=`${hideClass}` href='javascript:void(0);')
    + a.site-page.group.faa-parent.animated-hover(class=`${hideClass}` href='javascript:void(0);')
    if labelArray[1]
    - i.fa-fw(class=trim(labelArray[1]))
    + - var icon_label = trim(labelArray[1])
    + - var anima_label = labelArray[2] ? trim(labelArray[2]) : 'faa-tada'
    + if icon_label.substring(0,2)=="fa"
    + i.fa-fw(class=icon_label + ' ' + anima_label)
    + else if icon_label.substring(0,4)=="icon"
    + svg.icon(aria-hidden="true" class=anima_label)
    + use(xlink:href=`#`+ icon_label)
    span=' '+ trim(labelArray[0])
    i.fas.fa-chevron-down
    ul.menus_item_child
    each val,lab in value
    - const valArray = val.split('||')
    li
    - a.site-page.child(href=url_for(trim(valArray[0])))
    + a.site-page.child.faa-parent.animated-hover(href=url_for(trim(valArray[0])))
    if valArray[1]
    - i.fa-fw(class=trim(valArray[1]))
    + - var icon_val = trim(valArray[1])
    + - var anima_val = valArray[2] ? trim(valArray[2]) : 'faa-tada'
    + if icon_val.substring(0,2)=="fa"
    + i.fa-fw(class=icon_val + ' ' + anima_val)
    + else if icon_val.substring(0,4)=="icon"
    + svg.icon(aria-hidden="true" class=anima_val)
    + use(xlink:href=`#`+ icon_val)
    span=' '+ lab

    由于我的 Butterfly 版本为 4.3.0,版本跟参考文章作者不同,所以以上代码不是完全照搬的,自己做了一点修改。

    代码中的 if else 说明支持 fa、icon 前缀的写法。

  2. 以下是填写示例

    1
    2
    3
    menu:
    首页: / || icon-email # 引入阿里图标库图标
    时间轴: /archives/ || fas fa-archive

Social卡片图标引入

  1. 重写[Blogroot]\themes\butterfly\layout\includes\header\social.pug,替换为以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    each value, title in theme.social
    a.social-icon.faa-parent.animated-hover(href=url_for(trim(value.split('||')[0])) target="_blank" title=title === undefined ? '' : trim(title))
    if value.split('||')[1]
    - var icon_value = trim(value.split('||')[1])
    - var anima_value = value.split('||')[2] ? trim(value.split('||')[2]) : 'faa-tada'
    if icon_value.substring(0,2)=="fa"
    i.fa-fw(class=icon_value + ' ' + anima_value)
    else if icon_value.substring(0,4)=="icon"
    svg.icon(aria-hidden="true" class=anima_value)
    use(xlink:href=`#`+ icon_value)
  2. 以下为对应的social配置项,沿用menu_item的写法:

    1
    2
    3
    4
    5
    6
    7
    social:
    # iconfont多彩图标
    Github: url || icon-rat
    # fontawesome单色图标
    Email: url || fas fa-envelope
    # iconfont单色图标
    Bilibili: url || fa icon-ox

图标悬停动态效果

其实上面源码的一部分就是为了实现动态图标而修改的。想要静态图标可以去看参考文章。想不通有动态的图标为什么还要用静态的

  1. 插件

    1
    npm install font-awesome-animation
  2. CDN 引入

    1
    2
    3
    4
    inject:
    head:
    #动画标签anima的依赖
    - <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/l-lin/font-awesome-animation/dist/font-awesome-animation.min.css" media="defer" onload="this.media='all'">

在引入的图标后添加 || faa-tada 来实现动态效果,不过经测试发现不加一样有动态效果。

1
2
menu:
首页: / || fas fa-home || faa-tada