53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
/**
|
||
* 字体加载工具(core 层,不依赖任何 feature 模块)。
|
||
*
|
||
* 使用 wx.loadFontFace 将字体注册到 Canvas native 渲染管线,
|
||
* 按 URL 去重,同一字体只加载一次。
|
||
* 支持 HTTP/HTTPS 直链和 cloud:// 云存储文件 ID。
|
||
*/
|
||
|
||
/** 字体加载所需的最小描述 */
|
||
export interface FontFace {
|
||
/** wx.loadFontFace 的 family 参数 */
|
||
name: string;
|
||
/** 字体文件 URL(HTTP/HTTPS)或 cloud:// 文件 ID */
|
||
url: string;
|
||
}
|
||
|
||
const _loadedIds = new Set<string>();
|
||
|
||
/**
|
||
* 将 cloud:// 文件 ID 解析为临时 HTTPS URL。
|
||
* 非 cloud:// 的 URL 原样返回。
|
||
*/
|
||
async function resolveUrl(raw: string): Promise<string> {
|
||
if (!raw.startsWith('cloud://')) return raw;
|
||
const res = await wx.cloud.getTempFileURL({ fileList: [raw] });
|
||
const file = res.fileList?.[0];
|
||
if (file?.tempFileURL) return file.tempFileURL;
|
||
throw new Error(`cloud file resolve failed: ${raw}`);
|
||
}
|
||
|
||
/** 加载字体,同一 url 只加载一次 */
|
||
export async function loadFontFace(font: FontFace): Promise<void> {
|
||
if (_loadedIds.has(font.url)) return;
|
||
|
||
const resolved = await resolveUrl(font.url);
|
||
|
||
return new Promise((resolve, reject) => {
|
||
wx.loadFontFace({
|
||
family: font.name,
|
||
source: `url("${resolved}")`,
|
||
scopes: ['native'],
|
||
success: () => {
|
||
_loadedIds.add(font.url);
|
||
resolve();
|
||
},
|
||
fail: (err) => {
|
||
console.error(`loadFontFace [${font.name}] failed`, err);
|
||
reject(err);
|
||
},
|
||
});
|
||
});
|
||
}
|