如何在HTML画布上呈现图标字体,特别是Material Design图标字体?

4

这篇精彩的回答详细介绍了如何在HTML画布中包含FontAwesome图标。然而,从Material Design中调整图标字体的代码是无效的。所有代码都相同,只需将FontAwesome值替换为Material Design值。

以下是代码。

Codepen: https://codepen.io/Crashalot/pen/dyyEPWV

1)如何在HTML画布中并入Material Design的图标?

2)如何并入任何图标字体的图标(例如https://github.com/framework7io/framework7-icons)?

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 Material Icons')
                    .then(function (e) { done(me); })
                    .catch(failed);
            }
            l.href = '//fonts.googleapis.com/icon?family=Material+Icons';
            var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
        }());
    });
};

FontAwesome()
.then(function (fa) {

    var canvas = document.getElementById('mycanvas');
    const x = canvas.width / 2;
    const y = canvas.height / 2;

    // All set, and ready to render!
    var ctx = canvas.getContext('2d');
        ctx.textAlign = "center";
            ctx.textBaseline = "middle";
        ctx.font = '400px Material Icons';
        ctx.fillText(fa.get("airplanemode_active"), x, y);
});
1个回答

7
使用 FontFace 接口。
它只需要你字体文件的 URL。它的 load() 方法会返回一个 Promise,在字体准备好使用时解决。

const ctx = canvas.getContext('2d');

const material_font = new FontFace( 'material-icons',
  // pass the url to the file in CSS url() notation
  'url(https://fonts.gstatic.com/s/materialicons/v48/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2)' );
document.fonts.add( material_font ); // add it to the document's FontFaceSet

const framework7_font = new FontFace( 'framework7-icons',
  'url(https://cdn.jsdelivr.net/gh/framework7io/framework7-icons@master/fonts/Framework7Icons-Regular.woff2)' );
document.fonts.add( framework7_font );

// wait the font loads
material_font.load().then( () => {
  // we're good to use it
  ctx.fillStyle = 'green';
  ctx.font = '20px material-icons';
  ctx.fillText('airplanemode_active', 20, 40);
}).catch( console.error );

framework7_font.load().then( () => {
  ctx.fillStyle = 'blue';
  ctx.font = '20px framework7-icons';
  ctx.fillText('airplane', 20, 80);
}).catch( console.error );
<canvas id="canvas"></canvas>


再次感谢您的帮助,但它说这是一项实验性技术?https://developer.mozilla.org/en-US/docs/Web/API/FontFace - Crashalot
支持还不错:91% 如果你需要支持旧版浏览器如IE,则可以使用提供类似API的库,例如 https://github.com/bramstein/fontfaceobserver - Kaiido
还有,为什么您选择了woff2而不是TTF文件或其他通常与图标字体一起列出的字体文件呢? - Crashalot
如果字体已经显示,则浏览器已经加载了它,因此Promise将立即解析,但是拥有@font-face并不意味着它会被加载,您必须有一个使用该字体的渲染HTML元素,以便浏览器加载它。我选择woff2,因为这是网页字体的最佳格式。 - Kaiido
是的,但FontFace API实际上是编程中唯一可靠的了解它的方法。 - Kaiido
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接