【问题标题】:How to render icon fonts on HTML canvas and Material Design icon fonts in particular?如何在 HTML 画布上渲染图标字体,尤其是 Material Design 图标字体?
【发布时间】:2019-11-24 01:08:00
【问题描述】:

This wonderful answer 详细介绍了如何在 HTML 画布中包含来自 FontAwesome 的图标。但是,从 Material Design 调整图标字体的代码是行不通的。除了将 FontAwesome 值替换为 Material Design 值之外,所有代码都是相同的。

代码如下。

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

1) 如何将 Material Design 中的图标合并到 HTML 画布中?

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);
});

【问题讨论】:

    标签: javascript html canvas html5-canvas icons


    【解决方案1】:

    使用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>

    【讨论】:

    • 再次感谢您的帮助,但它说这是一项实验性技术? developer.mozilla.org/en-US/docs/Web/API/FontFace
    • 支持还不错:91% 如果您需要支持 IE 等旧版浏览器,那么您可以使用提供类似 API 的库,例如 github.com/bramstein/fontfaceobserver
    • 如果我们之前在页面上加载了字体,是否需要再次加载才能在画布元素中呈现?
    • 另外你为什么选择woff2而不是TTF文件或其他通常用图标字体列出的字体文件?
    • 如果字体被显示,那么浏览器已经加载了它,所以承诺会立即解决,但是,拥有@font-face 并不意味着它会被加载,你必须有一个使用此字体呈现 HTML 元素,以便浏览器加载它。我选择 woff2 是因为它是网络字体的最佳格式。
    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 2015-08-20
    • 2016-09-26
    • 2020-07-21
    • 2021-12-13
    • 2015-02-16
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多