Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解决在 Canvas 中使用自定义字体初次绘制文字时不生效的问题 #35

Open
yinxin630 opened this issue Apr 15, 2020 · 0 comments

Comments

@yinxin630
Copy link
Owner

yinxin630 commented Apr 15, 2020

请尝试如下代码, 需要先下载字体 http://d.xiazaiziti.com/en_fonts/fonts/a/Abril-Fatface.ttf

<!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);

问题原因是因为我们所用的字体需要异步加载, 它是在初次绘制文字时才开始加载的. 因为在初次绘制时, 字体还没有加载完毕, 所以会使用默认字体渲染

浏览器提供了检查相应字体是否加载完成的 API. document.fonts.check()

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 中绘制文本. 就可以解决问题了

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();
@yinxin630 yinxin630 changed the title Canvas 绘制文字时, 需要等待字体加载完成 在 Canvas 中使用自定义字体绘制文字时, 为什么第一次绘制没应用字体? Apr 15, 2020
@yinxin630 yinxin630 changed the title 在 Canvas 中使用自定义字体绘制文字时, 为什么第一次绘制没应用字体? 在 Canvas 中使用自定义字体绘制文字时, 为什么第一次绘制字体不生效? Apr 15, 2020
@yinxin630 yinxin630 changed the title 在 Canvas 中使用自定义字体绘制文字时, 为什么第一次绘制字体不生效? 解决在 Canvas 中使用自定义字体初次绘制文字时不生效的问题 Apr 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant