Angular中用户动态导入字体的问题及实现困惑
解决方案
1. 修复document.fonts.add()的TypeScript错误
这个报错是因为TypeScript默认DOM类型定义未完全覆盖FontFaceSet的add方法(现代浏览器均已支持该方法),可以通过两种方式解决:
方式一:临时类型断言
直接对document.fonts做类型断言,绕过类型检查:
loadFont() { const fontFace = new FontFace(this.fontName, `url(${this.fontLink})`); fontFace.load().then(loadedFont => { (document.fonts as any).add(loadedFont); // 字体加载完成后再执行Canvas渲染逻辑 this.renderCanvasText(); }).catch(err => { console.error('字体加载失败:', err); }); }
方式二:扩展DOM类型定义
在项目根目录创建dom.d.ts文件,补充FontFaceSet的类型定义,一劳永逸:
interface FontFaceSet { add(font: FontFace): void; }
2. 多字体动态加载的完整实现
要确保字体真正加载完成后再用于Canvas渲染,同时避免重复加载相同字体,可按以下流程实现:
步骤1:维护已加载字体缓存
在组件内定义一个对象记录已加载的字体,避免重复请求:
private loadedFonts: Record<string, FontFace> = {};
步骤2:通用字体加载方法
async loadCustomFont(fontName: string, fontUrl: string): Promise<void> { // 检查是否已加载过该字体 if (this.loadedFonts[fontName]) { console.log(`字体 ${fontName} 已加载`); return; } try { // 创建FontFace实例,可额外指定weight、style等属性 const fontFace = new FontFace(fontName, `url(${fontUrl})`); // 加载字体 await fontFace.load(); // 添加到文档字体集 document.fonts.add(fontFace); // 等待浏览器完成字体解析,确保可用 await document.fonts.ready; // 存入缓存 this.loadedFonts[fontName] = fontFace; console.log(`字体 ${fontName} 加载完成`); } catch (err) { console.error(`加载字体 ${fontName} 失败:`, err); throw err; } }
步骤3:Canvas中使用动态字体
调用加载方法后,确保字体可用再渲染文本:
async renderCanvasText() { const canvas = document.getElementById('myCanvas') as HTMLCanvasElement; const ctx = canvas.getContext('2d'); if (!ctx) return; // 加载用户选择的字体 await this.loadCustomFont(this.selectedFontName, this.fontLink); // 设置字体并渲染 ctx.font = '48px ' + this.selectedFontName; ctx.fillText('自定义字体测试', 50, 100); }
3. 处理用户上传本地字体文件
如果用户是上传本地字体文件(而非输入URL),需要将File对象转为Blob URL:
// 监听文件上传事件 handleFontFileUpload(event: Event) { const fileInput = event.target as HTMLInputElement; const file = fileInput.files?.[0]; if (!file) return; // 生成Blob URL const fontUrl = URL.createObjectURL(file); // 调用加载方法(fontName可由用户输入) this.loadCustomFont(this.userInputFontName, fontUrl); // 组件销毁时释放Blob URL,避免内存泄漏 // this.$once('hook:beforeDestroy', () => { // URL.revokeObjectURL(fontUrl); // }); }
4. 注意事项
FontFaceAPI支持Chrome 60+、Firefox 57+、Edge 79+,旧浏览器需做降级提示;- 加载跨域字体时,目标服务器需配置CORS允许你的域名访问,否则加载会失败。
内容的提问来源于stack exchange,提问作者quantom
相关产品推荐
相关产品推荐

