如何轻松地将自定义字体放入HTML5 Canvas?

Bre*_*dan 3 javascript css html5 canvas

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

dav*_*ave 6

虽然它还没有完整的支持,但您现在可以使用FontFace API显式加载字体,然后再在画布上使用它们.

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

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

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

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

});
Run Code Online (Sandbox Code Playgroud)

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

  • 这是比接受的答案更好的解决方案。 (2认同)
  • 在我将f.load()行更改为f.load()之前,这对我不起作用。然后(功能(字体){document.fonts.add(font);` (2认同)

Bre*_*dan 4

我将在下面讨论我的代码。首先,我的 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);
        }
Run Code Online (Sandbox Code Playgroud)

请允许我解释一下这里发生了什么。我有一个简单的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
Run Code Online (Sandbox Code Playgroud)

当然,我已经在画布、网页正文和必要的隐藏 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>
Run Code Online (Sandbox Code Playgroud)

如上所述,div 必须先加载字体,然后画布才能实现它。这就是为什么我里面有“词”。

我真的希望这可以帮助别人,因为我根本找不到任何东西。请向我提问,在下面的评论部分告诉我我可以做哪些不同的事情,或者只是简单地简化我的代码。我很感激您的帮助和建设性的批评。谢谢,祝您画布愉快...