加载第三方字体,检测加载完成事件

最近在做一个项目涉及到加载第三方字体的问题,首批需要支持一百多种字体,然后首先想到的就是@fant-face,但是在实际应用中发现无法满足当前需求. 目前的项目是用canvas的一个开源库fabric.js实现图片和文字的拖动,放大,缩小,旋转等操作,需要对文字设置不同字体的功能,首先就用的@fant-face,因为之前没用过,本来以为是只要用@fant-face定义的字体文件会在页面加载就去加载字体文件,实践发现并非这样,本来还想着在选择字体的时候再去动态添加对应文字的@fant-face,后来发现只有在页面中有用到这个字体时才回去加载,那就不用那么麻烦了,直接全部写入css中. 但是又遇到了一个问题,就是在fabric.js创建的canvas画布中,只有在第一次设置字体的时候如果字体已经加载完成才能渲染成功,否则就渲染不成功,那只能想其他办法了. 然后就去搜了一大堆监控字体加载完成相关的,最后发现了一个神器document.fonts,接下来就介绍一下怎么使用.

//加载字体文件
   obj格式,cssValue为自定义字体的名字,url为自定义字体的文件路径
    loadFont(obj){
        if(document.fonts&&!this.checkFont(obj.cssValue))
        {
            let that=this;
            let fontFamily=obj.cssValue;
            console.log(obj);
            let fontFace = new FontFace(obj.cssValue, `local('${obj.cssValue}'),url('${obj.url}') format('ttf'),url('${obj.url}')`);
            fontFace.load().then(function(loadedFontFace) {
                document.fonts.add(loadedFontFace);
                that.canvasDemo.updateTextFontFamily(fontFamily);
            });
        }
    },
    //检测字体文件是否已加载
    checkFont(name){
        let values=document.fonts.values();
        let isHave=false;
        let item=values.next();
        while(!item.done&&!isHave)
        {
            let fontFace=item.value;
            if(fontFace.family==name)
            {
                isHave=true;
            }
            item=values.next();
        }
        return isHave;
    }
复制代码

这样就可以监控到字体加载完成的事件,然后在完成事件中去更新canvas的文字内容了.目前发现document.fonts不支持ie,在ff中会自动缓存字体文件,但是在chrome中无法缓存,刷新页面之后在使用的话document.fonts中就找不到相关的字体了,加了local()也无法缓存,目前还未解决此问题.

posted on 2019-01-30 10:26  Jeffbee  阅读(3260)  评论(0编辑  收藏  举报