如何在字体加载完成后再用Canvas绘制指定字体文本?
解决Canvas字体加载完成后再绘制文本的问题
一、针对Google Fonts等Web字体的修正方案
document.fonts.ready 依赖浏览器将字体纳入FontFaceSet,但部分场景下@import引入的字体可能未被正确追踪,导致触发时机提前。改用document.fonts.load()显式加载目标字体,能精准确保字体就绪后再执行绘制:
function draw() { var canvas = document.getElementById("my_canvas"); var ctx = canvas.getContext("2d"); ctx.canvas.width = 150; ctx.canvas.height = 150; ctx.fillStyle = "red"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = "40px Special Elite"; ctx.fillStyle = "white"; ctx.fillText("hello", 25, 50); } // 显式请求加载指定字号和字体的资源 document.fonts.load("40px Special Elite").then(() => { draw(); });
二、针对本地自定义字体的方案
对于@font-face引入的本地字体,推荐通过FontFace API显式注册并追踪加载状态,避免浏览器未识别字体的情况:
方式1:JS注册并加载字体(更可靠)
// 注册本地字体 const customFont = new FontFace("custom_font", "url(some_font_file.ttf)"); // 加载完成后添加到文档并执行绘制 customFont.load().then((font) => { document.fonts.add(font); draw(); }).catch((err) => { console.error("字体加载失败:", err); }); function draw() { var canvas = document.getElementById("my_canvas"); var ctx = canvas.getContext("2d"); ctx.canvas.width = 150; ctx.canvas.height = 150; ctx.fillStyle = "red"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = "40px custom_font"; ctx.fillStyle = "white"; ctx.fillText("hello", 25, 50); }
方式2:保留CSS @font-face,用load()校验
如果继续使用CSS的@font-face,同样可以通过document.fonts.load()确保字体就绪:
document.fonts.load("40px custom_font").then(() => { draw(); });
三、额外注意事项
- 本地字体文件路径需与页面同源,或配置CORS允许跨域加载
- 可添加错误捕获逻辑,避免字体加载失败时页面无响应
- 多字体场景下,可用
Promise.all()批量加载所有字体后再执行绘制
内容的提问来源于stack exchange,提问作者Matías Cánepa
相关产品推荐
相关产品推荐

