如何使用已加载的自定义字体在HTML Canvas中绘制文本?
问题根因
你遇到的问题核心是自定义字体未完成加载就执行了Canvas绘制逻辑。CSS的@font-face默认是懒加载的,只有页面中存在实际使用该字体的DOM元素时才会触发资源请求,而Canvas的文本绘制不会触发字体加载,且如果绘制时字体未加载完成,浏览器会自动降级使用默认字体。
可行解决方案
方案1:使用Font Face API(推荐,现代浏览器兼容)
直接通过JS API主动加载字体,等待字体加载完成后再执行Canvas绘制操作,代码如下:
// 主动加载自定义字体 const customFont = new FontFace('olden-empire', 'url(path-to-the-font.ttf)'); customFont.load().then(loadedFont => { // 将加载完成的字体加入文档字体集合 document.fonts.add(loadedFont); // 此时再执行Canvas绘制逻辑 const canvas = document.getElementById("canvas"); const graphicsContext = canvas.getContext("2d"); graphicsContext.font = "20px olden-empire"; graphicsContext.fillText("hello world", 100, 100); }).catch(err => { console.error('字体加载失败:', err); });
方案2:旧浏览器兼容方案
如果需要适配不支持Font Face API的旧版浏览器,可以通过隐藏DOM元素提前触发字体加载,待字体加载完成后再执行绘制:
- 首先在HTML中加入一个不可见的元素触发字体加载:
<span style="font-family: 'olden-empire'; opacity: 0; position: absolute; top: -9999px;">.</span>
- 监听字体加载完成后执行绘制:
document.fonts.ready.then(() => { const canvas = document.getElementById("canvas"); const graphicsContext = canvas.getContext("2d"); graphicsContext.font = "20px olden-empire"; graphicsContext.fillText("hello world", 100, 100); });
注意事项
- 确认字体文件路径配置正确,若字体存放在跨域域名下需要配置正确的CORS规则
- 设置
graphicsContext.font时的字体名称,必须和@font-face中定义的font-family完全一致,大小写敏感 - 建议配置兜底字体,避免字体加载失败后文本显示异常,示例:
graphicsContext.font = "20px olden-empire, system-ui, sans-serif";
内容的提问来源于stack exchange,提问作者Coder_Naveed
相关产品推荐
相关产品推荐

