解決在 Canvas 中使用自定義字體初次繪製文字時不生效的問題

原文連接: github.com/yinxin630/b…
技術交流: fiora.suisuijiang.com/css

請嘗試以下代碼, 須要先下載字體 d.xiazaiziti.com/en_fonts/fo…html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <style> @font-face { font-family: "Abril Fatface"; font-style: normal; font-weight: 400; src: url("./abril-fatface-v9-latin-regular.ttf") format("truetype"); } </style>
  </head>
  <body>
    <canvas width="600" height="400"></canvas>
    <script> const $canvas = document.querySelector("canvas"); const ctx = $canvas.getContext("2d"); ctx.font = "32px Abril Fatface"; ctx.fillText("Draw text in canvas with special font", 20, 100); </script>
  </body>
</html>
複製代碼

image
如圖, 自定義字體並無生效. 但若是嘗試在初次繪製後, 延時一段時間再次繪製, 就沒問題

ctx.fillText("Draw text in canvas with special font", 20, 100);
setTimeout(() => {
  ctx.clearRect(0, 0, 600, 400);
  ctx.fillText("Draw text in canvas with special font", 20, 100);
}, 500);
複製代碼

問題緣由是由於咱們所用的字體須要異步加載, 它是在初次繪製文字時纔開始加載的. 由於在初次繪製時, 字體尚未加載完畢, 因此會使用默認字體渲染git

瀏覽器提供了檢查相應字體是否加載完成的 API. document.fonts.check()github

ctx.font = "32px Abril Fatface";
console.log(document.fonts.check(ctx.font)); // false
ctx.fillText("Draw text in canvas with special font", 20, 100);
複製代碼

瀏覽器還提供了等待字體加載完成和主動加載字體的 API. document.fonts.ready / document.fonts.load(). 咱們能夠直接觸發字體加載, 而後等待字體加載完畢後, 再在 canvas 中繪製文本. 就能夠解決問題了canvas

async function drawText() {
  ctx.font = "32px Abril Fatface";
  await document.fonts.load(ctx.font);
  ctx.fillText("Draw text in canvas with special font", 20, 100);
}
drawText();
複製代碼

image

另外你還能夠經過 js 而不是 css 來加載字體, 這樣會更方便些瀏覽器

async function drawText() {
  const AbrilFatface = new FontFace('Abril Fatface', 'url(./Abril-Fatface.ttf)', { style: 'normal', weight: 400 });
  await AbrilFatface.load();
  ctx.font = "32px Abril Fatface";
  ctx.fillText("Draw text in canvas with special font", 20, 100);
}
drawText();
複製代碼
相關文章
相關標籤/搜索