Search code examples
javascriptcsshtmlcanvas

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:


Solution

  • 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');
                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. 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 {
                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. 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:

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