阿里巴巴矢量图标库 (以下称iconfont)提供了方便的图标分享和管理功能。但是由于其图标项目独立于代码仓库,往往导致同一项目更换开发人员之后,接任者不能继续管理原来的图标库,给开发带来各种不便。
由于 iconfont 生成的 svg
文件含有图标路径以及图标名数据,因此 (对于保留了此 svg 文件的项目)可以从此 svg
文件中提取出所有图标,然后上传至图标库,重新构建图标项目。
1. svg 文件模板
SVG
的相关知识可以在 SVG | MDN (mozilla.org) 学习。
为了生成完整的 svg
文件,为其准备了一个文件模板字符串:
// svg 文件模板
const svgTemplate =
`<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
t="1584762969678"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
p-id="12392"
width="200"
height="200"
>
<defs><style type="text/css"/></defs>
<path d="__PATH__" />
</svg>`;
其中的 d
参数为 svg
路径,这里用 __PATH__
占位,以便后面作字符串替换。
2. 切割 .svg 文件
iconfont
生成的 .svg
文件包含了所有图标的路径,用 /<glyph[^n]*/>/g
可以匹配到每一个图标,并借此将它们分离并存储在一个数组里:
readFile(resolve(__dirname, svgPath), 'utf8', (err, res) =>{
const iconArray = res.match(/<glyph[^n]*/>/g);
}
3. 分离各图标的参数
使用正则从分离后的各图标里匹配出其对应的 name
、unicode
和路径信息:
iconArray.forEach(item => {
// 分离 unicode
const unicode = item.match(/unicode="&#(d+);"/)[1];
// 分离类名即图标名
const className = item.match(/glyph-name="([w-_]+)"/)[1];
// 分离路径
const path = item.match(/ d="([^"]*)"/)[1]);
});
4. 替换模板文件里的路径并写入文件
将 svg
模板字符串中的 __PATH__
替换成匹配到的路径:
fs.writeFile(
path.resolve(outputPath, className + '.svg'),
svgTemplate.replace('__PATH__', path),
function(err){if(err){throw err}}
);
5. 其他
其实分离出来的 SVG
图标的形状、尺寸、位置等参数会有偏移,不能直接上传到项目里使用,需要调整 transform
参数,在本文对应的 GitHub 仓库里提供了一个参数,但是使用中可能不符合实际情形,需要作进一步的调整。
本文只简述实现原理,不包含完整代码,完整代码已经上传到一个 GitHub 仓库中,可以按照其 readme
文件使用,此处不再赘述。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。