【问题标题】:How do I put custom fonts into HTML5 Canvas easily?如何轻松地将自定义字体放入 HTML5 Canvas?
【发布时间】:2015-05-28 16:22:16
【问题描述】:

在查看问题时,我从未找到上述问题的明确答案。我想要一种适用于几乎所有平台的方法。所以为了社区的利益,我想我会分享我在让自定义字体在画布上工作的成功。我的主要问题是,让所述字体工作的可靠方法是什么?我尝试了多种方法,例如仅使用 CSS 样式表,但它比这更复杂一些。这是我发现的:

【问题讨论】:

标签: javascript css html canvas


【解决方案1】:

更新:此解决方案 now works 适用于除 IE 11 及以下版本之外的所有浏览器。

虽然它没有完全支持,但您现在可以使用 FontFace API 在画布上使用字体之前显式加载字体。

var f = new FontFace('Font name', 'url(/path/to/font.ttf)');

f.load().then(function(font) {

  // Ready to use the font in a canvas context
  console.log('font ready');

  // Add font on the html page
  document.fonts.add(font);

  ctx.font = '48px Font name';
  ctx.strokeText('Hello world', 100, 100);

});

我可以确认这适用于 Chrome 61.0.3163.100、Safari 11.0 (12604.1.38.1.7)、Firefox 56.0(所有 OSX)和 Safari iOS 11.1。

【讨论】:

  • 这是一个比公认答案更好的解决方案。
  • 这对我不起作用,直到我将 f.load() 行更改为 f.load().then(function(font) { document.fonts.add(font);
  • 非常感谢这对我帮助很大,我从任何地方都得到了相同的代码,但它没有用,但之后我看到了这个答案,document.fonts.add(font); 到处都缺少这条线
【解决方案2】:

可能会丢失的重要一点是,在画布上使用的每种字体也必须通过设置画布元素的 font-family 样式属性来加载。

这是我使用 jquery 的版本。就绪事件消除了任何超时的需要。

<head>
 <script src="jquery-3.3.1.min.js"></script>
  <style>
    @font-face {
      font-family: 'AlexBrush';
      src: url('fonts/AlexBrush-Regular.ttf');
    }
    @font-face {
      font-family: 'Pacifico';
      src: url('fonts/Pacifico.ttf');
    }
  </style>
</head>
<body>
  <canvas id='testCanvas' width='1200px' height='800px'></canvas>
  <script>
    $(document).ready(function()
    {
        $('#testCanvas').css('font-family', "AlexBrush");
        $('#testCanvas').css('font-family', "Pacifico");
        var ctx = c.getContext("2d");
        ctx.fillStyle = "#000";
        ctx.font = "100px AlexBrush";
        ctx.fillText('Hello World', 100, 300);
        ctx.font = "100px Pacifico";
        ctx.fillText('Hello World', 100, 500);
    })
  </script>
</body>

【讨论】:

    【解决方案3】:

    我将在下面讨论我的代码。 首先,我的 Javascript:

    window.onload = function start() {
                canvas = document.getElementById('canvas1');
                C_Width = canvas.width;
                C_Height = canvas.height;
                cxt = canvas.getContext('2d');
                setTimeout(text_handler,200);
            }
    
            function text_handler() {
            console.log('made it!');
            cxt.font="20px myFont";//font size and then font family.
            cxt.fillStyle="white"; //color to be seen on a black canvas, default is black text
            cxt.fillText("TEST",(C_Width/2-200),C_Height/2); //cxt.fillText("message",x_coord,y_coord);
            }
    

    请允许我解释一下这里发生了什么。我有一个简单的window.onload 函数,以便在我尝试获取其 Id 和上下文之前画布存在。在我的text_handler() 函数中,我在一行中定义了字体大小和字体系列,以及我的字体颜色(白色,因为我有一个黑色画布)。然后在画布中绘制我的信息,并提供一个 x 坐标和一个 y 坐标。 setTimeout(); 延迟可能是必要的,以便让画布有时间加载字体。在我编写的测试程序中,我实际上把延迟时间降得很低,虽然 100 毫秒几乎不明显。 另一个关键部分是 CSS 样式表:

    canvas {
                background-color: black; //for white text
                font-family:myFont; //necessary
            }
            #load {
                font-family:myFont; //necessary to load font with div
                visibility: hidden; //makes div invisible but the div element forces the text to load before the canvas.
                height: 0px;
            }
            @font-face {
                font-family:myFont; 
                src: url('./Font_Path.ttf');
                } //self-explanatory
    

    我当然已经定义了画布中的字体、网页的正文和必要的隐藏 div。 div 有助于加载字体。我有样式以使 div 保持不可见,但它仍然可以工作。出于某种原因,通过我的测试,我确定font-family 样式必须在我的div 中的其他样式之上。当然,你可以使用任何你想要的东西。当然,我也使用@font-face 作为我的自定义字体。

    HTML 如下所示:

    <body>
        <div id="load">words</div> <!-- load font -->
        <canvas id="canvas1" width="500px" height="500px"></canvas>
    </body>
    

    如上所述,在画布可以实现它之前,div 是加载字体所必需的。所以我里面有“词”。

    我真的希望这对某人有所帮助,因为我根本找不到任何东西。请向我提问,在下面的评论部分告诉我我可以做些什么不同的事情,或者只是简单地简化我的代码的方法。我将不胜感激帮助和建设性的批评。谢谢,祝你画布快乐...

    【讨论】:

    • 还有最后一件事我忘了说。在调用text_handler() 函数之前可能需要延迟。
    • this 是否适用于您的场景?
    • 干得好。您在评论中提到的延迟非常重要。您可以查看@KenFyrstenberg 的链接,了解如何在代码尝试在画布中使用它之前等待字体完全加载。 ;-)
    猜你喜欢
    • 2018-09-26
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 2013-02-09
    • 2016-04-06
    相关资源
    最近更新 更多