iconfont-builder
iconfont-builder copied to clipboard
SVGO file and unicode codepoints.
我使用 iconfont-builder 处理 SVGO 压缩过的 SVG 文件,最终 TTF 文件中有些图标会出问题 (使用未压缩的 SVG 不会出问题)。
我另外一种方式直接使用 svgicons2svgfont 和 svg2ttf 的,使用 SVGO 压缩过的 SVG 文件生成的 TTF,并没有问题。
代码如下:
var fs = require("fs");
var path = require("path");
var yaml = require("js-yaml");
var svgicons2svgfont = require('svgicons2svgfont');
var svg2ttf = require('svg2ttf');
var svgFolder = "./assets/svg";
var fontFolder = "./assets/font";
var codepoints = yaml.safeLoad(fs.readFileSync("codepoints.yaml"));
var fontStream = svgicons2svgfont({
fontName: 'hello',
fontHeight: 960,
normalize: true
});
// Setting the font destination
fontStream.pipe(fs.createWriteStream('./assets/font/hello.svg'))
.on('finish',function() {
var ttf = svg2ttf(fs.readFileSync('./assets/font/hello.svg').toString());
fs.writeFileSync('./assets/font/myfont.ttf', new Buffer(ttf.buffer));
console.log('Font successfully created!');
})
.on('error',function(err) {
console.log(err);
});
fs.readdirSync(svgFolder).forEach(function (file) {
var svgFile = path.join(svgFolder, file);
if (fs.statSync(svgFile).isFile() && path.extname(svgFile) == ".svg") {
var glyphName = path.basename(file, ".svg");
var glyphCode = codepoints[glyphName];
if (glyphCode) {
var unicode = "0x" + glyphCode;
var glyph = fs.createReadStream(svgFile);
glyph.metadata = {
unicode: [String.fromCodePoint(unicode)],
name: glyphName
};
fontStream.write(glyph);
}
}
});
fontStream.end();
使用 iconfont-builder 的代码
var fs = require("fs");
var path = require("path");
var yaml = require("js-yaml");
var builder = require('iconfont-builder');
var codepoints = yaml.safeLoad(fs.readFileSync("codepoints.yaml"));
var svgFolder = "./assets/svg";
var fontFolder = "./assets/font";
var glyphs = [];
fs.readdirSync(svgFolder).forEach(function (file) {
var svgFile = path.join(svgFolder, file);
if (fs.statSync(svgFile).isFile() && path.extname(svgFile) == ".svg") {
var glyphName = path.basename(file, ".svg");
var glyphCode = codepoints[glyphName];
if (glyphCode) {
console.log(glyphCode);
glyphs.push({
name: glyphName,
file: file,
codepoint: "0x" + glyphCode
});
}
}
});
var options = {
icons: glyphs,
src: path.join(__dirname, svgFolder),
fontName: 'iconfont',
descent: 0,
dest: path.join(__dirname, fontFolder)
};
builder(options).then().catch();
codepoints.yaml
house: 2302
check: f050
print: f036
hourglass: 231b
watch: 231a
play: 25b6
plus: 2795
cross: f04f
info: 2139
出错的图标是 svgo 压缩后的 info.svg
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-1-8.5h2V17h-2v-5.5zm1-1.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/></svg>
原始的 info.svg, 从 Sketch 导出的。
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="#" fill="none" x="0" y="0" width="24" height="24"></rect>
<path d="M12,22 C6.4771525,22 2,17.5228475 2,12 C2,6.4771525 6.4771525,2 12,2 C17.5228475,2 22,6.4771525 22,12 C22,17.5228475 17.5228475,22 12,22 Z M12,20 C16.418278,20 20,16.418278 20,12 C20,7.581722 16.418278,4 12,4 C7.581722,4 4,7.581722 4,12 C4,16.418278 7.581722,20 12,20 Z M11,11.5 L13,11.5 L13,17 L11,17 L11,11.5 Z M12,10 C11.1715729,10 10.5,9.32842712 10.5,8.5 C10.5,7.67157288 11.1715729,7 12,7 C12.8284271,7 13.5,7.67157288 13.5,8.5 C13.5,9.32842712 12.8284271,10 12,10 Z" id="Combined-Shape" fill="#000000" fill-rule="nonzero"></path>
</svg>
另外一个问题是,设计从 Unicode 网站查找到的或者 macOS Fontbook 是编码都是 16 进值的。我使用 16 进值码之后,HTML 文件显示图标就有问题。
第一个问题我看一下,有同事也遇到 sketch 上的图标导出不能用的问题。
第二个问题能更详细描述下么?咱们在 HTML 上是怎么写字体的呢。
sketch 上的图标导出不能用,可能跟设计有关吧。我目前只发现被 SVGO 压缩过的 SVG,用原始的svgicons2svgfont 和 svg2ttf 是转的字体是完整的,而 iconfont-builder 却出问题,这个比较奇怪。
我参考 Google material-design-icons 使用 16 进值,我在 Unicode 完整下载的码表也是 16 进值。
改成这样就可以显示。
<i class="icon iconfont"></i>
<div class="name">check</div>
<div class="code">&#xF050;</div>
原来是这样的。
<i class="icon iconfont">�xf050;</i>
<div class="name">check</div>
<div class="code">&#x0xf050;</div>
@Ashung 是这样,&#
是 html 转义的起始字符,后面一般跟的是十进制,如果要使用十六进制,需要以 &#x
最为起始字符。也就是说,咱们之前的写法 �xf050
冗余了。
对,问题是生产的HTML好像没区分用户使用十进制或十六进制。可是你为什么要用十进制?
@Ashung 这里是生成字体的输入,而且也支持 16 进制,我看你传的就是 16 进制嘛,这个会进行转换的。采用十进制是考虑到我们的 code 可能会从数据库里取,库里是十进制的。
@Ashung 你说用 svgo 压过的样式有问题,这个后来我看了下:现在我们内部的解决方案还是规范 SVG 的设计,在设计时路径一定要闭合,形状必须合并。其实我这个也是依赖 svgicons2svgfont 和 svg2ttf,理论上生成的结果应该是一样的。