Jump to content

Custom font works oddly with game.add.text


Recommended Posts

I'm using game.add.text to place text on the canvas, and I'm using a TTF font defined in my page's <style> block with the @font-face declaration. The problem is, the font never seems to load the first time around -- it only works after about a second or so.


I tried setting the default fonts on the canvas element using CSS, but that doesn't seem to solve the problem.


Is there a way to declaratively pre-load TTF fonts for use in a game? The docs talk about loading bitmap fonts but that isn't what I'm trying to do.

Link to comment
Share on other sites

I had this situation with general canvas use (not Phaser specific) and I found a solution that seemed to work for me. If you add the @font-face rule as you did in your CSS, load it before any JS, and a also put an element on the page with one character and the style set to that font, it should load it before it gets to your JS. So, something <div>.</div>, set the div's font to the custom font, and then just absolutely position it off screen somewhere. I don't think you can use display: none; to hide it, because then the font won't load. Give that a try.

Link to comment
Share on other sites

  • 3 months later...

Just in case anyone else needs this, I use another method to fix the font issues: I simply add a new text in the Boot or Preload State, before any other text is rendered, and set it very small or out of the screen. Every text that comes after that one will have the font loaded.

this.game.add.text(0, 0, "fix", {font:"1px MyCustomFont", fill:"#FFFFFF"});

This way you don't need to add extra HTML elements and CSS styles.

Link to comment
Share on other sites

Personally I worked around it by loading the fonts in the surrounding HTML page's CSS and when the game starts, delay 2 seconds to allow the font to load before anything displays.  It's a bit of a hack but it works, I've tested it on PC's in a few different locations / connection speeds.  Of course depending how big your TTF file is you might have to delay longer.  I used a simple ZX spectrum style font in my game and it loads quickly, but still I need that 2 seconds delay for it to work straight away.


So in my HTML page I have the following in the <head> section.  (In my example I use a CSS3 font-face but could just be a TTF).

    <style type="text/css">                @font-face {            font-family: 'gameFont';            src: url('fonts/zx_spectrum-7-webfont.eot');            src: url('fonts/zx_spectrum-7-webfont.eot?#iefix') format('embedded-opentype'),                                  url('fonts/zx_spectrum-7-webfont.ttf') format('truetype'),                 url('fonts/zx_spectrum-7-webfont.svg#zx_spectrum-7regular') format('svg');            font-weight: normal;            font-style: normal;        } </style>

And then at the top of my javascript I have:

// phaser font styles (use in conjunction with css font face)var fontStyleMain = {    font: "48pt gameFont",    fill: "#ffffff",         shadowOffsetX: 0,    shadowOffsetY: 0,    shadowBlur: 8,    shadowColor: '#000000'};var txtTitle;

And then I can refer to it thus in the preload() function:

// wait a moment to allow CSS and fonts to load    game.time.events.add(2000, function () {               txtTitle = game.add.text(100, 50, "MR. GOGGLES", fontStyleMain);         // ***** the rest of your preload code goes here ***** //    },this);

This then gives a 2000 millisecond (2 sec) delay and the font will be loaded by the time you display anyhing.  You would have to experiment with this number to suit your TTF font.


Here's the page if you want to see it working:  http://www.owensouthwood.com/mrgoggles

Link to comment
Share on other sites

  • 2 years later...
  • 10 months later...

I faced problem like you and did not like solution to wait for N seconds or wait for user input, here is 100% working and proper solution:

var on_device_ready = function() {
  // https://github.com/bramstein/fontfaceobserver  
  var font_calibri = new FontFaceObserver('Calibri');

  Promise.all([font_calibri.load()]).then(function () {
    game = new Phaser.Game(...)
window.onload = on_device_ready;

Within your index.html file you should add

  @font-face {
    font-family: 'Calibri';
    src: url('assets/font/Calibri-Bold.woff') format('woff'),
    url('assets/font/Calibri-Bold.ttf') format('truetype');
    font-weight: bold;
    font-style: normal;

It may take some time before you can do everything correctly but I used this method on thousands of old/new mobiles and it works fine

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...