3

I have a custom font (*.ttf), that I am using to write text on the HTML canvas using Kinetic.js.

Unfortunately, on the first loading of the page it is not using my custom font, when reloading the page all is good.

Can I preload the font somehow?

I have tried this, but still not working:

<link rel="prefetch" href="resource/font/IDAutomationHC39M.ttf">

Can I tell Kinetic.js to preload it somehow?

The font is defined in my CSS like this:

@font-face {
    font-family: "Barcode";
    src: url(../font/IDAutomationHC39M.ttf);
}

Thanks in advance for your support!

Scott Weldon
  • 9,673
  • 6
  • 48
  • 67
Nik
  • 2,863
  • 6
  • 24
  • 29
  • does the problem only happen in kinetic.js? – btevfik Mar 21 '13 at 06:36
  • in which order do you load everything in `head` tag of the `html`? – bart s Mar 21 '13 at 06:37
  • loading it all in the head tag. Don't think its Kinetic.js - specific. Seems more likely to be a thing with the HTML canvas and that it can just used already loaded fonts, otherwise it falls back to default.. Any ideas? – Nik Mar 21 '13 at 06:55
  • is your font-face in an external css? if not put it there and try – btevfik Mar 21 '13 at 07:18
  • you can also try to put a div before the canvas element that makes the font load `
    `
    – btevfik Mar 21 '13 at 07:21
  • still not working.. it always fails to draw the text in the right font on first load... any more ideas? – Nik Mar 21 '13 at 10:08
  • There should be a way for you to load the font, and once the page is ready, then draw the canvas. Try JQuery's .ready() function and put all your KineticJS code inside it. That way your canvas will be drawn after your page loads, it's like waiting to load an image and then drawing it on the canvas. – SoluableNonagon Mar 21 '13 at 14:59

6 Answers6

11

I had a same problem today.. I ended up using this

<style>
@font-face {
    font-family: 'ArchivoBlack-Regular';
    src: url('../fonts/ArchivoBlack-Regular.ttf');
}
</style>

<div style="font-family:'ArchivoBlack-Regular'">&nbsp;</div>

After that you can do you normal KineticJS Stuff..! Actually its necessary to Load the Font first before using it..! I'm not good in English, but i hope u got my point. Also have a look at that link: Github Link

casper123
  • 1,736
  • 4
  • 21
  • 39
5

May be it is late to answer but it's worth mentioning with a full example.

Please note that KonvaJS is derived from KeneticJS and is supported, but Keneticjs is not supported anymore.

window.onload = function () {
var stage = new Konva.Stage({
      container: 'container',
      width: 1000,
      height: 1000
    });

    var layer = new Konva.Layer();

    var simpleText = new Konva.Text({
      x: stage.getWidth() / 10,
      y: 15,
      text: "\uf21c",
      fontSize: 300,
      fontFamily: 'FontAwesome',
      fill: 'green'
    });
  layer.add(simpleText);
  stage.add(layer);
  
}
  @font-face {
    font-family: 'FontAwesome';
    src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/fonts/fontawesome-webfont.ttf');
    font-weight: normal;
    font-style: normal;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
   <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"/>
  <script src="https://cdn.rawgit.com/konvajs/konva/0.11.1/konva.min.js"></script>
  <title>JS Bin</title>
</head>
<body>
  <div id="container" style="font-family:'FontAwesome'">dummyText</div>
</body>
</html>

Many thanks to @luschn for his great answer because as he stated: "timeout is bad solution".

Mahdi Alkhatib
  • 1,954
  • 1
  • 29
  • 43
4

You could use this old css hack to force the font to be available:

Add a hidden element to the page that specifies Barcode font

<span id="mustLoadMe">

And then in the CSS:

#mustLoadMe
{
    visibility: hidden;
    position: absolute;
    font-family: Barcode, Arial, Sans-serif;
}

Finally, use jQuery to wait on the font to load before drawing text in your canvas.

$("#mustLoadMe").load(function() {
       // do your canvas stuff here because the font should be loaded now...
});

Note: You might have to resort to $(window).load() in step#3 above to account for certain browsers async loading of fonts.

markE
  • 102,905
  • 11
  • 164
  • 176
4

It usually works in all browsers, you just have to use font-face correctly. Just use a generator like this one: http://www.fontsquirrel.com/tools/webfont-generator

It creates a zip files with 4 font files (eot, svg, ttf, woff), and there is a css file with the necessary code:

@font-face {
    font-family: 'myfont';
    src: url('myfont.eot');
    src: url('myfont.eot?#iefix') format('embedded-opentype'),
         url('myfont.woff') format('woff'),
         url('myfont.ttf') format('truetype'),
         url('myfont.svg#myfont') format('svg');
    font-weight: normal;
    font-style: normal;
}

I am using KineticJS, when i create the stage after page load it works with the correct font:

window.onload = function () {
    var stage = new Kinetic.Stage({
            container: 'container',
            width: 800,
            height: 600
    });
    //code for creating a layer, text and whatnot with kinetic
}

Should also be no problem if you don´t use Kinetic, of course.

If it does not work in some browsers, the font may not be loaded correctly. Using a timeout would be a bad workaround imho, you can try adding a hidden div right after the opening body tag:

<div class="font-hack" style="font-family:'your-font';">nothing to see here, move along</div>

It does not matter what you write there (it must not be empty though).

I am not working with Kinetic anymore, but this works great with the Phaser Engine.

andyrandy
  • 72,880
  • 8
  • 113
  • 130
2

I had the same problem with FontAwesome. Here is my solution:

//wait for fontawsome to load
setTimeout(function(){
   kineticStuff();
}, 500);

No need to add an element to your page.

Aïssa
  • 670
  • 8
  • 10
  • timeouts are very bad workarounds, you can usually avoid them. check out my answer, you just need an additional div as "font hack". works great with kinetic/konva or phaser. – andyrandy Feb 23 '16 at 14:53
2

Via Google's webfontloader https://github.com/typekit/webfontloader

testStrings need to be used to determine whether or not a font with glyphs has loaded. If your font do not have glyphs or custom subsets, you do not need to use testStrings

 WebFont.load({
     custom: {
         families: ['fontFamily1'],
         testStrings: {
             'fontFamily1': '\uE600'
         },
     },
     timeout: 5000 // Set the timeout to five seconds
         ,
     fontactive: function(familyName, fvd) {
        // the font have been loaded and now you can do what you want
     },
     fontinactive: function(familyName, fvd) {
         // the font could not be loaded  
     },
 });
Razan Paul
  • 13,618
  • 3
  • 69
  • 61