2

Canvas.filltext won't render custom font (though body text will, and canvas.filltext will render local fonts)

I want to paint some text on a canvas, using a custom font called jelleebold. Here's an abbreviated version of the function that I hoped would do that:

function paintLinkNameOnCanvas(linkName, canvas){
    let context = canvas.getContext('2d');
    context.font = "25px jelleebold";
    context.fillText(linkName, 50, 50);             
    return canvas;
}

However, the font that gets used is whatever the browser (Chrome) uses as its fallback (Times New Roman, I think). Here's the html link

<link href="./CSS/stylesheet.css" rel="stylesheet" type="text/css">

and the css, downloaded from fontsquirrel, and modified to suit my local directory structure:

@font-face {
    font-family: jelleebold;
    src: url('/fonts/jellee-roman-webfont.woff2') format('woff2'),
         url('/fonts/jellee-roman-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

I believe that this has worked, and Jelleebold has loaded successfully, because index.php contains:

<body style ="font-size: 50px; font-family: 'jelleebold'">
    <div id= "output" >
    test
    </div> 

    etc.

and the word 'test' gets printed in jelleebold.

In contrast, if the paintLinkNameOnCanvas function specifies a font that is installed on the local machine (such as context.font = "25px 'Balford Base'"), the linkname does get painted in that font.

So why isn't the custom font being used to paint the linkname on the canvas?


And after a very helpful suggestion from Renato Bibiano, I've now produced an updated version of the function (shown below). The commented lines are a hint about the next problem; how do I get it to work with both woff- and woff2-formatted fonts? It works with either one, but not the other.

function paintLinkNameOnCanvas(linkName, canvas){
    let earl = "";
//      earl += "url('/fonts/jellee-roman-webfont.woff' ) format('woff' ";
//      earl += ", ";
        earl += "url('/fonts/jellee-roman-webfont.woff2')format('woff2')";
    let f = new FontFace("jelleebold", earl);
    f.load().then(function() {
        let context = canvas.getContext('2d');
        context.font = '23px jelleebold';
        context.fillText('Hey, world', 0, 100);               
        });
    return canvas;
}

I feel that taking the comment slashes out should produce something sensible, but if both specifications (woff and woff2) are included, the ouput reverts to the default font, TNR.

struggling
  • 21
  • 6
  • The browser might not be done loading the font file perhaps, at that moment when you paint the text onto the canvase. With your normal body text content, the browser re-renders the text when the font is done loading, but with your pixels drawn onto the canvas that of course doesn’t happen. See https://stackoverflow.com/questions/29248182/how-do-i-put-custom-fonts-into-html5-canvas-easily for some approaches to make sure the font is done loading. – 04FS Jan 30 '19 at 08:52
  • I've added a follow-up to my original query. I tried to add it as a comment, but it was too big, so I've edited the original query - the follow-up is after the line of asterisks. – struggling Jan 30 '19 at 12:15
  • It should work the same way for multiple font source URLs, as the `@font-face` declaration in CSS does, https://stackoverflow.com/a/41100077/10955263 – 04FS Jan 30 '19 at 12:21
  • There are other ways to determine when fonts have finished loading, maybe try one of those - https://stackoverflow.com/questions/5680013/how-to-be-notified-once-a-web-font-has-loaded – 04FS Jan 30 '19 at 12:22
  • 'The browser might not be done loading' Yes, that's what "f.load() then..." is meant to handle. 'It should work the same way for multiple font source URLs, as the @font-face declaration in CSS does.' And I THOUGHT I'd formatted the url string that way... let f = new FontFace("jelleebold", "url('/fonts/jellee-roman-webfont.woff' ) format('woff' ), url('/fonts/jellee-roman-webfont.woff2') format('woff2')" ); – struggling Jan 31 '19 at 12:31
  • Not sure if that’s a browser bug or not … try one of the other solutions maybe. – 04FS Jan 31 '19 at 12:49

0 Answers0