导读:本期聚焦于小伙伴创作的《如何在HTML Canvas中应用自定义字体并实现异步加载》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在HTML Canvas中应用自定义字体并实现异步加载》有用,将其分享出去将是对创作者最好的鼓励。

在HTML Canvas的绘图场景中,默认的字体样式很难满足个性化的视觉设计需求,给Canvas文本应用自定义字体并处理好加载逻辑,是保证绘图效果符合预期的关键步骤。自定义字体的应用需要结合CSS的字体定义和Canvas的字体属性设置,同时因为字体文件加载是异步过程,还需要做好加载状态的判断,避免出现字体未加载完成就渲染文本导致的显示异常。

如何在HTML Canvas中应用自定义字体并实现异步加载

Canvas文本绘制基础语法

Canvas绘制文本主要依赖两个核心方法,分别是填充文本绘制和描边文本绘制,使用前需要先设置上下文的字体属性。字体属性的设置格式和CSS的font属性一致,包含字体大小、字体族等参数。

基础的文本绘制示例如下:

// 获取Canvas元素和上下文
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 设置字体:大小 字体族
ctx.font = '24px sans-serif';
// 设置填充颜色
ctx.fillStyle = '#333';
// 绘制填充文本,参数分别为文本内容、起始x坐标、起始y坐标
ctx.fillText('默认字体文本', 50, 100);

// 设置描边颜色
ctx.strokeStyle = '#ff0000';
// 绘制描边文本
ctx.strokeText('描边文本示例', 50, 150);

自定义字体的引入方式

要让Canvas识别自定义字体,首先需要通过@font-face规则在CSS中定义字体,指定字体文件的路径和字体族名称,之后Canvas的上下文才能通过该字体族名称调用对应的自定义字体。

CSS中定义自定义字体的代码如下:

/* 定义自定义字体 */
@font-face {
    font-family: 'MyCustomFont';
    /* 字体文件路径,支持多种格式兼容不同浏览器 */
    src: url('https://ipipp.com/fonts/my-custom-font.woff2') format('woff2'),
         url('https://ipipp.com/fonts/my-custom-font.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

定义完成后,就可以在Canvas的font属性中使用MyCustomFont这个字体族名称,示例如下:

// 设置自定义字体
ctx.font = '24px MyCustomFont';
ctx.fillStyle = '#0066cc';
// 绘制自定义字体文本
ctx.fillText('自定义字体文本', 50, 200);

自定义字体的异步加载处理

字体文件的加载是异步过程,如果直接在定义完@font-face后就调用自定义字体绘制文本,很可能字体还没加载完成,Canvas会使用默认字体替代渲染,导致显示效果不符合预期。因此需要监听字体的加载状态,等字体加载完成后再执行绘制逻辑。

现代浏览器提供了FontFace API和document.fonts.ready接口来处理字体加载监听,推荐使用document.fonts.ready的方式,兼容性更好且使用更简单。

使用document.fonts.ready监听加载

document.fonts.ready返回一个Promise,当所有通过CSS定义的字体都加载完成后,这个Promise会变为fulfilled状态,我们可以在这个状态的回调中执行文本绘制逻辑。

// 等待所有字体加载完成
document.fonts.ready.then(() => {
    // 字体加载完成后执行绘制
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    // 此时自定义字体已经加载完成,可以正常使用
    ctx.font = '24px MyCustomFont';
    ctx.fillStyle = '#333';
    ctx.fillText('字体加载完成后绘制的文本', 50, 250);
}).catch(err => {
    console.error('字体加载失败:', err);
    // 加载失败时使用默认字体兜底
    ctx.font = '24px sans-serif';
    ctx.fillText('字体加载失败,使用默认字体', 50, 250);
});

单个字体加载状态判断

如果只需要监听某一个自定义字体的加载状态,可以使用FontFace API单独加载并监听该字体,示例如下:

// 创建自定义字体对象
const customFont = new FontFace('MyCustomFont', 'url(https://ipipp.com/fonts/my-custom-font.woff2)');
// 将字体添加到文档的字体集中
document.fonts.add(customFont);
// 加载字体
customFont.load().then(() => {
    console.log('自定义字体加载完成');
    // 执行绘制逻辑
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    ctx.font = '24px MyCustomFont';
    ctx.fillText('单独加载的自定义字体文本', 50, 300);
}).catch(err => {
    console.error('单个字体加载失败:', err);
});

常见问题与解决方案

  • 字体不生效:检查@font-face中定义的字体族名称和Canvas中使用的名称是否完全一致,包括大小写;检查字体文件路径是否正确,能否正常访问。
  • 首次加载字体闪烁:可以在页面初始化时就触发字体加载,而不是等到需要绘制Canvas的时候再加载,提前加载可以减少用户等待时间。
  • 跨域字体加载失败:如果字体文件放在不同域的服务器上,需要服务器配置CORS响应头,允许当前域访问字体资源,否则浏览器会阻止字体加载。

完整示例代码

以下是一个包含自定义字体定义、异步加载监听、Canvas文本绘制的完整示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas自定义字体示例</title>
    <style>
        @font-face {
            font-family: 'MyCustomFont';
            src: url('https://ipipp.com/fonts/my-custom-font.woff2') format('woff2'),
                 url('https://ipipp.com/fonts/my-custom-font.woff') format('woff');
            font-weight: normal;
            font-style: normal;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="600" height="400"></canvas>
    <script>
        // 等待所有字体加载完成
        document.fonts.ready.then(() => {
            const canvas = document.getElementById('myCanvas');
            const ctx = canvas.getContext('2d');
            // 绘制默认字体文本
            ctx.font = '20px sans-serif';
            ctx.fillStyle = '#666';
            ctx.fillText('默认字体示例', 50, 50);
            // 绘制自定义字体文本
            ctx.font = '24px MyCustomFont';
            ctx.fillStyle = '#ff6600';
            ctx.fillText('自定义字体异步加载示例', 50, 100);
            // 绘制描边自定义字体文本
            ctx.strokeStyle = '#009900';
            ctx.lineWidth = 1;
            ctx.strokeText('自定义描边字体', 50, 150);
        }).catch(err => {
            console.error('字体加载异常:', err);
        });
    </script>
</body>
</html>

HTML_Canvas自定义字体异步加载font_facedrawText修改时间:2026-07-11 09:27:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。