Javascript 如何轻松地将自定义字体放入HTML5画布?

Javascript 如何轻松地将自定义字体放入HTML5画布?,javascript,css,html,canvas,Javascript,Css,Html,Canvas,当浏览这些问题时,我从未找到上述问题的明确答案。我想要一种几乎适用于所有平台的方法。因此,为了社区的利益,我想分享一下我在画布上使用自定义字体的成功经验。我的主要问题是,什么是让所说的字体起作用的可靠方法?我尝试了多种方法,比如只使用CSS样式表,但比这要复杂一些。以下是我的发现:我将在下面讨论我的代码。 首先,我的Javascript: window.onload = function start() { canvas = document.getElementById

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

我将在下面讨论我的代码。 首先,我的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);
        }
请允许我解释一下这是怎么回事。我有一个简单的
窗口。onload
函数,以便在我尝试获取画布的Id和上下文之前画布已经存在。在我的
text\u handler()
函数中,我在一行中定义了字体大小和字体系列,以及我的字体颜色(白色,因为我有黑色画布)。然后在画布中绘制消息,并提供x坐标和y坐标。
setTimeout()延迟可能是必要的,以便给画布加载字体的时间。在我编写的测试程序中,我实际上得到了非常低的延迟时间,尽管100ms几乎是不可见的。
另一个关键部分是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保持不可见,但它仍能完成它的工作。出于某种原因,通过测试,我确定
字体系列
样式必须高于div中的其他样式。当然,您可以使用任何您想要的样式。当然,我使用
@font-face
作为自定义字体

以下是HTML的外观:

<body>
    <div id="load">words</div> <!-- load font -->
    <canvas id="canvas1" width="500px" height="500px"></canvas>
</body>
如上所述,在画布实现字体之前,必须先加载该字体。这就是为什么我有“文字”在里面


我真的希望这能帮助一些人,因为我在上面找不到任何东西。请问我一些问题,告诉我在下面的评论部分我可以做些什么不同的事情,或者简单地说我可以简化我的代码。我非常感谢你的帮助和建设性的批评。谢谢,欢迎使用Canvas ing…

尽管它还没有完全的支持,但现在您可以使用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);

});

我可以确认,这在Chrome 61.0.3163.100、Safari 11.0(12604.1.38.1.7)、Firefox 56.0(所有OSX)和Safari iOS 11.1上都可以使用。

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

这是我使用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>

@字体{
字体系列:“AlexBrush”;
src:url('fonts/AlexBrush Regular.ttf');
}
@字体{
字体系列:“Pacifico”;
src:url('font/Pacifico.ttf');
}
$(文档).ready(函数()
{
$('#testCanvas').css('font-family','AlexBrush');
$('testCanvas').css('font-family','Pacifico');
var ctx=c.getContext(“2d”);
ctx.fillStyle=“#000”;
ctx.font=“100px-AlexBrush”;
ctx.fillText('helloworld',100300);
ctx.font=“100px Pacifico”;
ctx.fillText('helloworld',100500);
})

还有最后一件事我忘了提。在调用
text\u handler()
函数之前,可能需要延迟。这对您的场景有用吗?干得好。你在评论中提到的延迟是非常重要的。您可以查看@KenFyrstenberg的链接,了解如何处理在代码尝试在画布中使用字体之前等待字体完全加载的问题。;-)与公认的答案相比,这可能是一个更好的解决方案。直到我将
f.load()
行更改为
f.load()。然后(函数(字体){document.fonts.add(字体);