Skip to main content

如何在 HTML5 画布中使用自定义字体?

如何在 HTML5 画布上绘制外部字体?

如果您想在 Konva.Text 中使用自定义字体,只需执行以下步骤:

  1. 将字体样式添加到您的页面
  2. fontFamily 属性设置为所需的字体面。

但这里有一个重要的事情。当您为 DOM 元素(如 divspan)设置字体时,浏览器会在字体加载后自动更新这些元素。但这对于画布文本则不起作用。您需要再次重绘画布。

现代方法:CSS 字体加载 API

检测字体何时加载的最现代方法是使用 CSS 字体加载 API,它在所有现代浏览器中都得到了支持。

该 API 提供了一种干净、基于 Promise 的方式来加载和检测字体,而无需任何黑客或变通方法。

import Konva from 'konva';

// 建立我们的舞台
const width = window.innerWidth;
const height = window.innerHeight;

const stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

const layer = new Konva.Layer();
stage.add(layer);

// 添加一个默认字体的文本节点
const text = new Konva.Text({
  x: 50,
  y: 50,
  fontSize: 40,
  text: '带有自定义字体的文本。',
  width: 250,
  // 开始使用默认字体
  fontFamily: 'Arial'
});

// 添加另一个文本帮助调试字体加载
const debugText = new Konva.Text({
  x: 50,
  y: 0,
  fontSize: 16,
  text: '加载字体...',
  fill: 'green'
});

layer.add(text);
layer.add(debugText);

// 首先,通过样式表链接加载字体(更可靠)
const fontLink = document.createElement('link');
fontLink.href = 'https://fonts.googleapis.com/css2?family=Kavivanar&display=swap';
fontLink.rel = 'stylesheet';
document.head.appendChild(fontLink);

// 使用浏览器的字体加载机制检测何时准备好
document.fonts.ready.then(() => {
  // 检查我们的字体是否被加载
  if (document.fonts.check('1em Kavivanar')) {
    text.fontFamily('Kavivanar');
    debugText.text('字体加载成功!');
  } else {
    // 备选方案 - 尝试稍作延迟(某些浏览器的常见问题)
    setTimeout(() => {
      debugText.text('使用备选计时器 - 现在尝试设置字体');
      text.fontFamily('Kavivanar');
    }, 500);
  }
}).catch(err => {
  debugText.text('加载字体错误: ' + err.message);
  debugText.fill('red');
  console.error('字体加载失败:', err);
});