【问题标题】:Browsers lazy-loading fonts with FontFace浏览器使用 FontFace 延迟加载字体
【发布时间】:2019-08-19 18:00:19
【问题描述】:

所以,我正在使用 Canvas API 开发一个简单的网页游戏。我需要使用指定的字体在画布中绘制字符。

在加载例程中,我使用 promises 来等待我需要的字体,如下所示:

Promise.all([
    (new FontFace("LCD Solid", "url('assets/LCD_Solid.ttf')")).load().then((font)=>{
        document.fonts.add(font)
    }, (err)=>{
        throw {type: "font_loading_err", fontName: "LCD Solid", DOMException: err}
    }),
    (new FontFace("Conformity", "url('assets/Conformity.ttf')")).load().then((font)=>{
        document.fonts.add(font)
    }, (err)=>{
        throw {type: "font_loading_err", fontName: "Conformity", DOMException: err}
    }),
]).then(loadGame, oops)

promise 已解决,但未加载。 Chrome 和 Firefox 仅在我使用 fillText() 时加载它们,在 Chrome 中使用默认衬线字体生成一些帧,直到字体加载。

根据the spec,promise 应该只在字体加载时才被解析,但它也允许延迟加载。

有什么方法可以避免延迟加载字体并强制浏览器在那个时候加载它们?

【问题讨论】:

    标签: javascript font-face cssom


    【解决方案1】:

    我认为FontFaceObserver 在这里很适合你。您仍然可以使用 JS API 或通常的 @font-face CSS API 加载字体,并且 FontFaceObserver 将帮助您在加载字体时触发其他内容。

    这是一个完整的示例,结合了您的代码和 FontFaceObserver README 中的多种字体示例:

    <canvas id="js-canvas"></canvas>
    <script src="https://unpkg.com/fontfaceobserver@2.1.0/fontfaceobserver.standalone.js"></script>
    <script>
    var exampleFontData = {
      'Family A': { weight: 400, src: 'url(assets/FamilyA-Regular.woff2), url(assets/FamilyA-Regular.woff)' },
      'Family B': { weight: 400, src: 'url(assets/FamilyB-Regular.otf)' },
      // Etc.
    }
    
    var observers = []
    var fonts = []
    
    // Make one Observer along with each font
    Object.keys(exampleFontData).forEach(function(family) {
      var data = exampleFontData[family]
      var obs = new FontFaceObserver(family, data)
      var font = new FontFace(family, data.src)
    
      observers.push(obs.load())
      fonts.push(
        font
          .load()
          .then((f) => {
            document.fonts.add(f)
          }, (err) => {
            throw {type: "font_loading_err", fontName: family, DOMException: err}
          })
      )
    })
    
    Promise.all(fonts)
    .then(() => {
      console.log('Use the canvas')
      var canvas = document.getElementById('js-canvas')
      canvas.width = 750
      canvas.height = 500
      var ctx = canvas.getContext('2d')
    
      ctx.font = '36px "Family A"'
      ctx.fillText('HELLO USING FONT', 20, 50)
    
      ctx.font = '36px "Family B"'
      ctx.fillText('Hello using font', 20, 150)
    }, (err) => {
      console.error(err)
    })
    </script>
    

    希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 2015-01-16
      相关资源
      最近更新 更多