原文链接: github.com/yinxin630/b…
技术交流: fiora.suisuijiang.com/
请尝试如下代码, 需要先下载字体 d.xiazaiziti.com/en_fonts/fo…
<!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>
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();
另外你还可以通过 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();