React Canvas组件渲染时字体加载失败问题求助
解决React Canvas组件字体加载延迟问题
问题说明
React Canvas组件首次渲染时,指定的Great Vibes、Ubuntu等字体未完成加载,导致Canvas文本默认显示系统字体(如Comic Sans),仅刷新页面后才会显示目标字体。已尝试Font Face构造器、CSS配置、本地字体导入、Google Fonts链接等方案,均未解决。
核心原因
组件挂载后立即执行Canvas绘制逻辑,但此时字体文件尚未加载完成,Canvas API会自动回退到系统默认字体;刷新页面时字体已被浏览器缓存,因此能正常显示。
解决方案
通过FontFace API手动管理字体加载流程,确保所有目标字体加载完成后再执行Canvas绘制操作:
1. 封装字体加载函数
在组件内部创建加载所需字体的异步函数,使用Promise.all等待所有字体加载完成:
const loadFonts = async () => { // 加载Great Vibes字体(本地文件示例,根据实际路径调整) const greatVibes = new FontFace( 'Great Vibes', 'url("../fonts/GreatVibes-Regular.woff2") format("woff2")' ); // 加载Ubuntu字体 const ubuntu = new FontFace( 'Ubuntu', 'url("../fonts/Ubuntu-Regular.woff2") format("woff2")' ); // 添加字体到文档 await greatVibes.load(); document.fonts.add(greatVibes); await ubuntu.load(); document.fonts.add(ubuntu); // 等待字体在文档中完全可用 await document.fonts.ready; };
2. 控制Canvas绘制时机
新增状态标记字体加载状态,修改useEffect逻辑,仅在字体加载完成后执行绘制:
import React, { useEffect, useRef, useState, useCallback } from "react"; // ... 保留其他导入 ... const Canvas = ({ height, width, imageUrl, courseId }) => { const canvasRef = useRef(null); const { userId, userName } = useParams(); const [fontsLoaded, setFontsLoaded] = useState(false); // 标记字体加载完成 // 用useCallback包裹draw函数,避免频繁重建 const draw = useCallback((context) => { // ... 保留原draw函数所有内容 ... }, [courseId, userId, userName]); const loadFonts = async () => { // 上述字体加载代码 await document.fonts.ready; setFontsLoaded(true); }; useEffect(() => { loadFonts(); }, []); useEffect(() => { if (!fontsLoaded) return; // 字体未加载完成时跳过绘制 const canvas = canvasRef.current; const context = canvas.getContext("2d"); const image = new Image(); image.onload = () => { context.drawImage(image, 0, 0, width, height); draw(context); }; image.src = imageUrl; }, [draw, height, width, imageUrl, fontsLoaded]); // 添加fontsLoaded依赖 // ... 保留原return部分 ... };
3. 额外优化点
- 确保字体路径正确:本地字体文件建议放在
public/fonts目录下,使用绝对路径(如"/fonts/GreatVibes-Regular.woff2")避免路径解析错误 - 若使用Google Fonts,可在
loadFonts函数中通过document.fonts.check()验证字体是否加载完成,替代本地文件加载逻辑
内容的提问来源于stack exchange,提问作者wolfie00
相关产品推荐
相关产品推荐

