终极效果
效果要求:使得最终页面效果在开发者模拟器、安卓、iOS都可正常显示字体效果。
问题背景
如何在微信小程序上利用wx.loadFontFace方法加载自己要上传的字体的文件一直是困扰很多开发者的问题,很多人反映使用该方法在开发者工具模拟器上是可以显示的,有的开发者说在模拟器和iOS系统上可以正常显示自定义字体,但是安卓机上无法正常显示。
很多人为了能够实现加载自定义字体想了很多办法,比如
方法1:
字体文件转base64代码(如网站https://www.transfonter.org) ,然后存储在wxss文件中。这也是我曾使用的方法之一,确实很好用,安卓/苹果机上都可以正常实现效果。
缺点:但是面对字体文件包一般都很大的中文字体来说,转换成base64代码是极容易出现仅用来引用字体的wxss代码就超过2M的情况。
根据小程序的开发规矩,即使采用分包形式开发一个小程序,单个分包的代码量也是不能超过2M的,此时就是该方法的鸡肋。
方法2:
也有开发者利用iconfont上的在线引用方法,把自己会用到的字输进入然后点击生成字体,引用一个url即可实现。这种方法也是可行的。
缺点:但是对于部分字多或者可能出现用户输入文字的情况,这种方法就不太方便。
解决方案
今天,和大家讲的就是wx.loadFontFace方法,也是很多人一直在尝试,执着于想要利用这种方法实现。
在小程序开发者文档中,这一段文字是你不陌生的。
wx.loadFontFace(Object object)
基础库 2.1.0 开始支持,低版本需做兼容处理。
本接口从基础库版本 2.15.0 起支持在小程序插件中使用
动态加载网络字体,文件地址需为下载类型。‘2.10.0’起支持全局生效,需在 app.js 中调用。
注意:
字体文件返回的 contet-type 参考 font,格式不正确时会解析失败。
字体链接必须是https(ios不支持http)
字体链接必须是同源下的,或开启了cors支持,小程序的域名是servicewechat.com
canvas等原生组件不支持使用接口添加的字体
工具里提示 Faild to load font可以忽略
’2.10.0’ 以前仅在调用页面生效。
——来源于《微信小程序开发者文档》
分析:
注意点1是大家一般无需担心的,我们下载到的字体文字很多是ttf文件,都是符合相关要求的。
注意点2也是一般不会犯错的,大家都会避开这个。
注意点3是非常重要的,也是很多开发者不明白的,下面,我会着重讲如何解决这个问题,解决了这个问题,无论调试还是真机都能正常显示。
在开发者文档中,有这样一段代码:
wx.loadFontFace({
family: 'Bitstream Vera Serif Bold',
source: 'url("https://sungd.github.io/Pacifico.ttf")',
success: console.log
})
可以看出使用的是https链接,或许你曾经拿这段代码测试过。
或者你也曾经把字体文件上传到一些存储空间然后得到上传后文件的地址,或者说你曾经在开发者社区看到别人上传的字体文件的https链接然后来调用。
在开发者工具模拟器上正常显示,一到真机就显示不了。
当然为了想要使用我自己喜欢的字体,得到该字体的文件链接,我也突然脑洞大开,尝试把字体文件上传到云开发的云存储上,然后得到一个FileID链接和一个下载链接。
随后在页面或者全局的JS中加载该字体文件:
代码:
loadFontFace() {
wx.loadFontFace({
family: 'XXX',
source: 'url("xxxxxx.ttf")',
success(res){
console.log('res', res)
},
fail(err){
console.log('err', err)
}
})
},
遗憾的是,也是能在模拟器中显示出自定义字体效果,在安卓的真机上无法正常显示,iOS未知(我没有iOS系统故无法测试)。
到底是怎么回事,问题出在哪呢?于是一遍遍琢磨开发文档中的注意事项“字体链接必须是同源下的,或开启了cors支持,小程序的域名是servicewechat.com”。
后来琢磨后面一句话,我也是不明白啥是cors,于是就搜索了,记得其中一篇文章就讲到腾讯云的cors之类的。
操作步骤
1 进入腾讯云的官网(https://cloud.tencent.com),然后登录账号,选择公众号小程序登录,扫码并选择需要实现自定义字体的小程序进行登录
2 在顶部菜单栏找到“对象存储”
3 存储桶列表中新建一个存储桶
4 给存储桶设置配置,跨域访问中设置好“cors规则”,把https://servicewechat.com域名填写到来源Origin的方框内。
现在再来读读“字体链接必须是同源下的,或开启了cors支持,小程序的域名是servicewechat.com”是不是有了新的体会。
5 把需要使用的字体文件上传到该存储桶,然后点击文件右边的“详情”,你就会看到“对象地址”,这个地址就可以粘贴到JS文件的wx.loadFontFace使用。
6 不要忘了设置刚刚上传的字体文件“访问权限”为“公有读私有写”,这样每个用户都可以读取这个字体文件了。
源码分享
JS文件
loadFontFace() {
wx.loadFontFace({
family: 'XXX(你给字体拟的名称,最好英文如kaiti)',
source: 'url("对象地址")',
success(res){
console.log('res', res)
},
fail(err){
console.log('err', err)
}
})
},
WXSS文件
page{
font-family: 'XXX'(你给字体拟的名称,最好英文如kaiti);
}
或者
.xxx(class名){
font-family:'xxx(你给字体拟的名称,最好英文如kaiti)'
}