You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 注意事项

  • FontFace API支持Chrome 60+、Firefox 57+、Edge 79+,旧浏览器需做降级提示;
  • 加载跨域字体时,目标服务器需配置CORS允许你的域名访问,否则加载会失败。

内容的提问来源于stack exchange,提问作者quantom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:57:28