# 图片和字体

> 稳定加载 Fabric.js 图片和字体：加载前检查每张图片，先加载字体，上传本地图片，解决跨域问题。

Source: https://fabricjs-document-engine.jscrate.dev/zh/docs/guides/assets-and-fonts
Last updated: 2026-09-28

Fabric.js 图片和字体是保存的文档重新打开后显示不对的最常见原因。图片链接过期了，字体还没加载，或者图片只存在于旧的标签页里。引擎会帮你把这些都检查一遍。

## 资源清单

每份保存的文档都会列出它需要的图片和字体，以及用到它们的对象 id：

```ts
const manifest = engine.getAssetManifest();
// { images: [{ url, objectIds }], fonts: [{ family, weight, style, objectIds }] }
```

以 `data:` URL 内嵌的图片不在清单里，因为它们不需要下载。

## 配置检查

```ts
const engine = createDocumentEngine({
  canvas,
  storage,
  assets: {
    resolveUrl: (url) => url.replace("asset://", "https://cdn.example.com/"),
    replaceMissingImage: () => "/placeholder.png",
    upload: async ({ blob }) => uploadToYourBucket(blob),
    loadFont: async ({ family, weight, style }) => {
      const face = new FontFace(
        family,
        `url(/fonts/${family}-${weight}.woff2)`,
        {
          weight,
          style,
        }
      );
      document.fonts.add(await face.load());
    },
    requireFonts: false,
  },
});
```

## 打开文档时

1. `resolveUrl` 可以改写每个保存的地址，比如给它签名，或把 id 映射到 CDN。
2. 每种字体和字重都会调用 `loadFont`。之后引擎会检查字体是否真的能渲染，而不是悄悄换成默认字体。
3. 所有图片并行加载。每张图片缺失时，`replaceMissingImage` 可以返回一个新地址，或返回 `null` 表示保持缺失。
4. 如果仍有图片缺失，加载会以 `MISSING_ASSETS` 失败。`error.missingAssets` 列出每个 `{ url, objectIds }`，画布不会被改动。

无法加载的字体会产生 `FONT_UNAVAILABLE` 警告，文字改用后备字体。设置 `requireFonts: true` 则改为以 `MISSING_FONTS` 失败。

## 保存文档时

只存在于当前标签页的图片（`blob:` 地址）和内嵌的 `data:` 图片，会各自交给 `upload` 上传一次，文档里保存返回的地址。没有 `upload` 处理函数时，`blob:` 图片会产生 `ASSET_NOT_PORTABLE` 警告，因为其他设备打不开它们。

## 跨域和导出

来自其他网站、又没有用 `crossOrigin: "anonymous"` 加载的图片会污染画布，导出 PNG 就会失败。引擎会用 `IMAGE_CROSS_ORIGIN` 警告你，让你尽早修复。请让图片服务器返回 `Access-Control-Allow-Origin` 头，并用 `crossOrigin: "anonymous"` 加载图片，这样跨域问题就解决了。

## 随时检查和替换

```ts
const report = await engine.checkAssets();
report.missingImages;
report.unavailableFonts;

await engine.replaceImage("/old-logo.png", "/new-logo.png");
```

`replaceImage` 会替换所有使用该地址的图片。每张图片在页面上的尺寸不变，整个替换是一步撤销。用户反馈图片缺失后，用它修复 Fabric.js 图片和字体问题很方便。
