Brendan Brendan - 7 months ago 19
CSS Question

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. Here's what I found:


I'll discuss my code underneath. First off, My Javascript:

window.onload = function start() {
            canvas = document.getElementById('canvas1');
            C_Width = canvas.width;
            C_Height = canvas.height;
            cxt = canvas.getContext('2d');

        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. 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). Then in the canvas I draw my message, and provide an x coordinate and a y coordinate. The 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. Another critical part of this is the CSS stylesheet:

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 {
            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. The div helps load the font. I have styles in order that the div remains invisible but it still does its job. For some reason, through my testing, I determined that the font-family style must be above the other styles in my div. Of course, you could use whatever you want. Also of course, I use @font-face for my custom font.

Here's what the HTML looks like:

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

As explained above, the div is necessary to load the font before the canvas can implement it. 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...