簡體   English   中英

瀏覽器使用 FontFace 延遲加載字體

[英]Browsers lazy-loading fonts with FontFace

所以,我正在使用 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)

承諾已解決,但未加載。 Chrome 和 Firefox 僅在我使用fillText()時加載它們,使用默認襯線字體創建一些框架,直到字體加載,在 Chrome 中。

根據規范,promise 應該只在加載字體時解決,但它也允許延遲加載。

有什么辦法可以避免延遲加載字體並強制瀏覽器在那個時候加載它們?

我認為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>

在畫布上使用字體的結果。

希望這有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM