1

I'm trying to import a font to use in the html5 canvas. I have the file on my computer, but everything I've tried so far hasn't worked. The canvas just displays a default font. I must be doing something wrong or missing a step.

I have loaded them in with CSS like this:

@font-face {
font-family: 'RifficFree-Bold';
src: local('RifficFree-Bold'), url(./fonts/RifficFree-Bold.ttf), format('truetype');
}

and then calling them in JS like so:

    function drawText(myText, ctx) {
        ctx.font = "40px RifficFree-Bold";
        ctx.fillStyle = "rgb(0, 0, 0, " + myText.fill + ")";
        ctx.fillText(myText.text, myText.x, myText.y);
    }

I know that the program is getting this far, as whenever I change 40px to another value, the size of the font changes as it should. I think I must be loading the actual font file incorrectly. Any ideas?

kelso
  • 43
  • 2
  • 7

2 Answers2

2

The custom font-face fonts are not loaded until they are used (you can read a question about this here). So when calling your drawText-function the font does not begin to load until ctx.fillText has been called- at which point the text has already been drawn using the default font.

You can force the browser to pre-load the font in two ways;

  1. Put a small, invisible div with some text using your font in it somewhere on the page (it can be removed after the font is loaded).

  2. If you need to load several fonts or don't want to modify your HTML, you can create a small function for loading fonts:

    function _loadFont(fontname){
        var canvas = document.createElement("canvas");
        //Setting the height and width is not really required
        canvas.width = 16;
        canvas.height = 16;
        var ctx = canvas.getContext("2d");
    
        //There is no need to attach the canvas anywhere,
        //calling fillText is enough to make the browser load the active font
    
        //If you have more than one custom font, you can just draw all of them here
        ctx.font = "4px "+fontname;
        ctx.fillText("text", 0, 8);
    }
    

    Just call the function before you need to use the font, and they should be loaded when you actually need them.

Jave
  • 31,598
  • 14
  • 77
  • 90
  • Hi there, thanks for the response. I did read somewhere about using a div to pre-load the font. I inserted this:
    TEST
    , but it did not work. Does what I have there look alright? I'll give the function a go now.
    – kelso Apr 16 '18 at 19:34
  • The function doesn't seem to work either... Which tells me my problem might lie elsewhere. – kelso Apr 16 '18 at 19:45
  • I tried your example with a different font, and it worked. Are you sure your browser supports TrueType-fonts? – Jave Apr 16 '18 at 19:46
  • Can I ask what browser you used? I've tested it in Firefox and Chrome and neither work. – kelso Apr 16 '18 at 19:52
  • @kelso, see my other answer which probably fixes your particular issue :) – Jave Apr 16 '18 at 19:53
2

The actual problem in your example seems to be the comma (,) between the url and format parameters. format should be directly following the url:

src: local('RifficFree-Bold'), url(./fonts/RifficFree-Bold.ttf) format('truetype');
Jave
  • 31,598
  • 14
  • 77
  • 90
  • I actually put that comment there myself as a test, it doesn't work without it either unfortunately :/ I'm baffled. – kelso Apr 16 '18 at 19:55
  • If that was not the problem, then I really don't know; I downloaded the same font, and copied your example. With the comma I get the warning `Unknown descriptor 'format(' in @font-face rule. Skipped to next declaration.`. Removing it displays the proper font. – Jave Apr 16 '18 at 20:00
  • Did you test it with the div and/or the function you suggested or without? – kelso Apr 16 '18 at 20:06
  • @kelso I copied your font-face declaration and your test div from your other comment. As is, it does not work. Removing the comma solved it. – Jave Apr 16 '18 at 20:08
  • Hey, just wanted to jump back in here and let you know that my fonts weren't showing because I wasn't referencing the .css file properly in my .html file. Oops. It works now. – kelso Apr 18 '18 at 00:06