wordpress插件嵌入webFont自定义字体

css引入自定义字体

img

使用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转换合并字体文件

img

python的第三方库fonttools可以将指定的内容生成字体文件的子集,同时可以转换为指定的文件格式。

对于wordpress博客而言,我们只需要转换当前文章内容所使用的字体即可,这样文件体积会非常小,能够解决上述痛点。

安装fonttools

pip install fonttools

使用方法

pyftsubset <字体文件> --text=<需要的字形> --output-file=<输出文件>

js引用网络字体(动态)

img

在制作插件的时候,考虑可以动态选择自定义字体。

如果使用完整的字体文件则直接切换指定的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可以实现动态加载字体,但是仍然遗留几个优化问题。

  1. 不想通过每次存储字体文件的形式来引用字体。

  2. 每篇文章内容对应不同字体的数据可以存入wordpress数据库,既能够减少第三方资源依赖,增加字体访问速度,还能够一键迁移所有wordpress数据。

加载arrayBuffer字体

img

参考链接:

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

img

因为fonttoolspython库,所以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())

这里生成的数据就是前端需要的数据

免费商用字体

img

使用字体一定要优先注意版权问题。

目前字体种类繁多,版权声明模糊不清,有的说可以免费商用,有的又说需要授权。

到底是哪一种一定要亲自到官网查证,不确定的建议不要使用。

具体可以参考Google Fonthttps://fonts.google.com/

也可以参考我之前写过的文章《9个免费可商用的字体推荐