简体   繁体   English

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

[英]How do I put custom fonts into HTML5 Canvas easily?

When looking through the questions I never found a clear answer to the above. 在查看问题时,我从未找到对上述内容的明确答案。 I wanted a method that worked with just about every platform. 我想要一种适用于几乎所有平台的方法。 So for the benefit of the community, I thought I'd share my success in getting custom fonts to work in canvas. 所以为了社区的利益,我想我会分享我在使用自定义字体在画布上工作的成功。 My main question was, What is a surefire way to get said fonts to work? 我的主要问题是,什么是让所述字体工作的万无一失的方法? I tried multiple methods such as just using a CSS stylesheet but it's a bit more complicated than that. 我尝试了多种方法,比如只使用CSS样式表,但它比这复杂一点。 Here's what I found: 这是我发现的:

Although it doesn't have complete support yet you can now use the FontFace API to explicitly load fonts before using them on a canvas. 虽然它还没有完整的支持,但您现在可以使用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);

});

I can confirm that this works on Chrome 61.0.3163.100, Safari 11.0 (12604.1.38.1.7), Firefox 56.0 (all OSX) and Safari iOS 11.1. 我可以确认这适用于Chrome 61.0.3163.100,Safari 11.0(12604.1.38.1.7),Firefox 56.0(所有OSX)和Safari iOS 11.1。

I'll discuss my code underneath. 我将在下面讨论我的代码。 First off, My Javascript: 首先,我的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);
        }

Allow me to explain whats going on here. 请允许我解释一下这里发生的事情。 I have a simple window.onload function so that the canvas exists before I try to get its Id and Context. 我有一个简单的window.onload函数,以便在我尝试获取其Id和Context之前存在画布。 Inside my text_handler() function, I have the font size and the font family defined in one line, as well as my font color (White because I have a black canvas). 在我的text_handler()函数中,我在一行中定义了字体大小和字体系列,以及我的字体颜色(白色,因为我有一个黑色画布)。 Then in the canvas I draw my message, and provide an x coordinate and ay coordinate. 然后在画布中我绘制我的信息,并提供一个x坐标和一个y坐标。 The setTimeout(); setTimeout(); delay may be necessary in order to give the canvas time to load the font. 延迟可能是必要的,以便给画布时间加载字体。 In the test program I wrote, I actually got the delay time down really low, though 100ms is almost unnoticeable. 在我写的测试程序中,实际上我的延迟时间确实很低,尽管100ms几乎不可察觉。 Another critical part of this is the CSS stylesheet: 另一个关键部分是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

I have of course defined the font in the canvas, the body of the webpage, and a necessary hidden div. 我当然定义了画布中的字体,网页的正文和必要的隐藏div。 The div helps load the font. div有助于加载字体。 I have styles in order that the div remains invisible but it still does its job. 我有样式,以便div保持隐形,但它仍然可以完成它的工作。 For some reason, through my testing, I determined that the font-family style must be above the other styles in my div. 出于某种原因,通过我的测试,我确定font-family风格必须高于我div中的其他风格。 Of course, you could use whatever you want. 当然,你可以使用你想要的任何东西。 Also of course, I use @font-face for my custom font. 当然,我也使用@font-face作为我的自定义字体。

Here's what the HTML looks like: 这是HTML的样子:

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

As explained above, the div is necessary to load the font before the canvas can implement it. 如上所述,div必须在canvas可以实现之前加载字体。 That's why I have "words" inside it. 这就是我内心有“话语”的原因。

I really hope this helps someone out because I simply couldn't find anything on it. 我真的希望这可以帮助别人,因为我根本找不到任何东西。 Please ask me questions, tell me what I could have done differently in the comment section below, or just simply ways I can simplify my code. 请问我一些问题,告诉我在下面的评论部分我可以做些什么,或者只是简单地简化我的代码。 I'd appreciate the help and constructive criticism. 我很感激帮助和建设性的批评。 Thanks, and happy Canvas-ing... 谢谢,快乐的画布......

An important point that might get lost is that each font that is used on canvas must also be loaded by setting the font-family style-attribute for the canvas element. 可能会丢失的一个重点是,还必须通过设置canvas元素的font-family style-attribute来加载画布上使用的每个字体。

Here's my version using jquery. 这是我使用jquery的版本。 The ready event removes the need for any timeouts. ready事件消除了对任何超时的需要。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM