原文链接:https://dsx2016.com/?p=1063
公众号:大师兄2016
使用css3
的@font-face
引入自定义字体
@font-face{
font-family: dsxFont; // 设置自定义字体的名称
src: url('https://dsx.com/dsxFont.ttf') // 引用字体资源-url或者本地文件
}
使用引入的字体
div{
font-family: dsxFont;
}
不考虑兼容性等问题,这里有一个不得不留意的地方:中文字体文件太大。
英文由于只有26
个字母,所以不论是哪一种字体,其文件体积也不会大于几十kb
。
由于汉字的总数约近于十万个,日常使用3000
字可覆盖大部分书面场景,但就算是这样,一个字体的文件也大概有5M
左右。
对于现在的网站访问来说,有极大的影响,不仅消耗流量,还损失了体验,得不偿失。
fonttools
转换合并字体文件python的第三方库fonttools
可以将指定的内容生成字体文件的子集,同时可以转换为指定的文件格式。
对于wordpress
博客而言,我们只需要转换当前文章内容所使用的字体即可,这样文件体积会非常小,能够解决上述痛点。
安装fonttools
pip install fonttools
使用方法
pyftsubset <字体文件> --text=<需要的字形> --output-file=<输出文件>
js
引用网络字体(动态)在制作插件的时候,考虑可以动态选择自定义字体。
如果使用完整的字体文件则直接切换指定的css
类即可,但是现在的前提是文章的每种字体文件都是根据文章内容实时变化。
这种情况不仅意味着需要根据当前文章内容实时生成指定的字体文件,且css
也需要动态引用新的字体文件url
。
可以通过js
来动态加载和设置字体集
// 使用网络字体文件资源实例化字体
let f = new FontFace('dsxFont', 'url(https://dsx.com/dsxFont.ttf)', {});
// 当字体资源加载完毕后
f.load().then(function (loadedFace) {
// 将字体加入当前网页的自定义字体集
document.fonts.add(loadedFace);
// 然后设置页面body元素的字体展示优先匹配刚引入的指定字体
document.body.style.fontFamily = 'dsxFont, serif';
});
虽然通过js
可以实现动态加载字体,但是仍然遗留几个优化问题。
不想通过每次存储字体文件的形式来引用字体。
每篇文章内容对应不同字体的数据可以存入wordpress
数据库,既能够减少第三方资源依赖,增加字体访问速度,还能够一键迁移所有wordpress
数据。
arrayBuffer
字体参考链接:
https://developer.mozilla.org/zh-CN/docs/Web/API/FontFace
FontFace()
接口:
既可以使用URL指向的外部资源,也可以使用ArrayBuffer
构造并返回一个新的 FontFace
对象。
后端api
接口可以读取字体文件返回base64
字符串,js
可以将base64
数据转为arrayBuffer
,同时base64
可以存储在数据库中。
所以这种方式即不需要文件资源上传,也可以存入wordpress
数据库(文章id关联标识),取出来也可以直接加载为网页字体资源。
// 获取base64数据-通过api接口或者wordpress自己的数据库
let base64Data=""
//封装base64转arrayBuffer函数
let base64ToUint8Array= (base64String) =>{
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
// 获取最终的 arrayBufferData
let arrayBufferData=base64ToUint8Array(base64Data);
//实例化字体资源
let f = new FontFace('dsxFont', arrayBufferData, {}); // // 使用arrayBuffer实例化字体-二进制数据缓冲区
// 当字体资源加载完毕后
f.load().then(function (loadedFace) {
// 将字体加入当前网页的自定义字体集
document.fonts.add(loadedFace);
// 然后设置页面body元素的字体展示优先匹配刚引入的指定字体
document.body.style.fontFamily = 'dsxFont, serif';
});
python API
读取文件返回base64
因为fonttools
为python
库,所以api
接口自然也是python
。
生成完精简的字体文件后,立马读取文件并返回base64
数据
# 引入base64模块
import base64
# 要读取的文件(字体文件)
path = './font.subset.ttf'
# 读取文件以二进制流的方式
f = open(path, 'rb')
# 转化为base64数据
base64_str = base64.b64encode(f.read())
# 打印在控制台(记得使用decode解码为不带b的字符串)
print(base64_str.decode())
这里生成的数据就是前端需要的数据
使用字体一定要优先注意版权问题。
目前字体种类繁多,版权声明模糊不清,有的说可以免费商用,有的又说需要授权。
到底是哪一种一定要亲自到官网查证,不确定的建议不要使用。
具体可以参考Google Font
:https://fonts.google.com/
也可以参考我之前写过的文章《9个免费可商用的字体推荐》