需求:就在字体加载完成时,将该字体的字绘制到canvas 中。假如该字体未加载完成前,使用canvas 绘制的就是默认字体的字。
涉及到的项目:青柠设计:https://qingning6.com/
一。如何判断一个字体是否加载完成。使用api :document.fonts.
/**
* 验证字体是否加载完成
* fonts => [{fontSize, fontFamily}]
* */
function validFonts(fonts) {
return new Promise(resolve => {
const fontFace = document.fonts
fonts.forEach(font => {
fontFace.load(`${font.fontSize}px ${font.fontFamily}`)
})
fontFace.onloadingdone = () => {
const state = fonts.every(font => {
return fontFace.check(`${font.fontSize}px ${font.fontFamily}`)
})
if (state) {
resolve()
}
}
})
}
说明:首先通过css加载需要加载的字体文件,然后通过 document.fonts 获取到 fontFace 对象。该对象有如下方法和事情。
- fontFace.load(font) : 用于加载一个字体。font :'12px sans-serif', 返回promise。
- fontFace.onloadingdone: 当你通过 load 加载的所有字体加载完成时触发。如果没有通过load 进行加载而是通过添加dom元素的形式进行加载的,可能会产生其他一个字体加载完成时,会触发该事情。而不是等所有字体加载完成后触发。
- fontFace.onloading: 字体加载时触发。测试发现不管你加载多少个字体,只会触发一次。
- fontFace.status: 加载的状态。
css 加载字体代码:
const loadFont = function (name, url) {
const fontFace = `@font-face {
font-family: '${name}';
font-display: swap;
src: url('${url}.eot'); /* IE9*/
src: url('${url}.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('${url}.woff2') format('woff2'),
url('${url}.woff') format('woff'), /* chrome、firefox */
url('${url}.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('${url}.svg#Alibaba-PuHuiTi-Regular') format('svg'); /* iOS 4.1- */
}`
const style = document.createElement('style')
style.innerText = fontFace
const head = document.head || document.getElementsByTagName('head')[0]
head.appendChild(style)
}
说明:name: 使用字体的名称,url: 不要带后缀名。函数里面会自动添加后缀名,然后根据系统去下载合适的字体。