有没有办法从 html5 canvas 访问字体图标?

Is there a way to access fonts icons from html5 canvas?

我是 html5 canvas 的新手。

我需要将字体图标 (fontawesome) 显示为图像。 这可能吗?谢谢

确实可以,就是有点麻烦

因为 Canvas 如果实际字体尚未准备好,将使用后备字体绘制,并且由于字体是延迟加载的,您需要暂停渲染直到字体准备好。这应该可以使用类似 Google/Typekit 的 Web 字体加载器 (https://github.com/typekit/webfontloader)

字体准备就绪后,您可以在 canvas 中绘制它,就像任何其他字符串一样,例如

var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = '48px FontAwesome';
  ctx.fillText(String.fromCharCode(61449), 10, 50);

最大的挑战是您必须重新映射 Font Awesome 中的所有符号,即它们的 JavaScript 字符表示形式。

编辑:

这实际上可以使用名称来完成,通过计算 CSS 规则

getFAChar = function (name) {
    var elm = document.createElement('i');
    elm.className = 'fa fa-' + name;
    elm.style.display = 'none';
    document.body.appendChild(elm);
    var content = window.getComputedStyle(
        elm, ':before'
    ).getPropertyValue('content')
    document.body.removeChild(elm);
    return content;
};

var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = '48px FontAwesome';
  ctx.fillText(getFAChar('bed'), 10, 50)

编辑:

为了提高性能,应该缓存 FA 图标,特别是如果 Canvas 经常重绘(尝试达到 60 fps 时添加和删除大量 DOM 元素不是一个好主意)

var FontAwesome = (function () {
    var me = {},
        FACache = {};

    function find (name) {
        var elm = document.createElement('i');
        elm.className = 'fa fa-' + name;
        elm.style.display = 'none';
        document.body.appendChild(elm);
        var content = window.getComputedStyle(
            elm, ':before'
        ).getPropertyValue('content')
        document.body.removeChild(elm);
        return content;
    };

    me.get = function (name) {
        if (!!FACache[name]) return FACache[name];
        var c = find(name);
        FACache[name] = c;
        return c;
    };
    return me;
}());

var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = '48px FontAwesome';
  ctx.fillText(FontAwesome.get('bed'), 10, 50);

编辑

使用延迟渲染、自动 css 注入和 css 字符映射的完整示例,尽管仅在 Chrome 中测试(使用字体加载 API 和无 polyfill 的承诺)

var FontAwesome = function () {
 return new Promise(function (done, failed) {
  var me = {},
   FACache = {};

  function find (name) {
   var elm = document.createElement('i');
   elm.className = 'fa fa-' + name;
   elm.style.display = 'none';
   document.body.appendChild(elm);
   var content = window.getComputedStyle(
    elm, ':before'
   ).getPropertyValue('content')
   document.body.removeChild(elm);
   return content;
  };

  me.get = function (name) {
   if (!!FACache[name]) return FACache[name];
   var c = find(name)[1];
   FACache[name] = c;
   return c;
  };
  
  (function() {
   var l = document.createElement('link'); l.rel = 'stylesheet';
   l.onload = function () {
    document.fonts.load('10px FontAwesome')
     .then(function (e) { done(me); })
     .catch(failed);
   }
   l.href = '//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css';
   var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
  }());
 });
};

FontAwesome()
.then(function (fa) {
    // All set, and ready to render!
    var ctx = document.getElementById('canvas').getContext('2d');
        ctx.font = '48px FontAwesome';
        ctx.fillText(fa.get('bed'), 10, 50);
});
<canvas id="canvas"></canvas>