MrBill

How to check if a font has been fully loaded into the PIXI.Text object?

Recommended Posts

I've noticed a small visual bug with the menu I have. When I startup the game for the first time in the browser (in a private window with no cookies), the "label" objects have their fonts properly display but the "button" objects do not. The buttons appear to display the default font instead.

image.thumb.png.d47c293111f07eba72fe27169b0e3dd0.png

However, once I have refreshed the page at least once, all fonts display properly for every subsequent refresh.

image.thumb.png.fe88b0cb6c732a85c4b5773a46873750.png

So this has me thinking that the font is not loading into the button object fast enough before it's drawn the first time and I'm wondering how I can fix that.

Here's some relevant code:

This function is responsible for creating the PIXI.Text for my custom label class.

Renderer.prototype.setLabelGraphic = function(label){
  let message = label.text;
  let style = this.textStyles[label.textStyle];
  let text = new PIXI.Text(message, style);
  label.graphic = text;
};

This function is responsible for creating the PIXI.Text and Rectangle for my custom button class.

Renderer.prototype.setButtonGraphic = function(button){
  let minimumWidth = 150;
  let minimumHeight = 50;
  let container = new PIXI.Container();

  // Create label component.
  let message = button.text;
  let textStyle = this.textStyles[button.textStyle];
  let text = new PIXI.Text(message, textStyle);

  // Create button component.
  let rectangle = this.configureButtonRect(button.style);
  let rectangleWidth = (text.width < minimumWidth) ? minimumWidth : text.width;
  let rectangleHeight = (text.height < minimumHeight) ? minimumHeight: text.height;
  rectangle.drawRect(0, 0, rectangleWidth, rectangleHeight);
  rectangle.endFill();

  // Center text within containing rectangle.
  let center = [(rectangleWidth / 2) - (text.width / 2), (rectangleHeight / 2) - (text.height / 2)]
  text.position.set(center[0], center[1]);

  // Combine them into the container.
  container.addChild(rectangle);
  container.addChild(text);

  button.graphic = container;
};

The configureButtonRect in the previous:

Renderer.prototype.configureButtonRect = function(buttonStyle){
  let rectangle = new PIXI.Graphics();
  let colour;
  if(buttonStyle === "default"){
    colour = 0xFFBF75;
    rectangle.lineStyle(2, 0xCA826C, 1);
  } else console.error(`Error configuring button rectangle: {buttonStyle} is not a valid button style.`);
  rectangle.beginFill(colour);
  return rectangle;
};

Drawing of either object is simply add their respective graphic attribute to the stage. I feel that the solution is to simply just have the game wait for the fonts load before adding to the container via promises or callbacks, but I'm not exactly sure which part of the code would be responsible for the delay.

Share this post


Link to post
Share on other sites

during your loading phaze, you can do something like this, is how i load my fonts.
is vanilla without libs, or you have some great libs on npm for less code.

return new Promise((resolve, rej) => {
                    const fontsList = [
                        new FontFace('ArchitectsDaughter', 'url(fonts/ArchitectsDaughter.ttf)', { style: 'normal', weight: 700 } ),
                        new FontFace('zBirdyGame', 'url(fonts/zBirdyGame.ttf)',{ style: 'normal', weight: 700 }),
                        new FontFace('Flux_Architect_Regular', 'url(fonts/Flux_Architect_Regular.ttf)',{ style: 'normal', weight: 700 }),
                        new FontFace('ampersand', 'url(fonts/ampersand.ttf)',{ style: 'normal', weight: 700 }),
                        new FontFace('ShadowsIntoLight', 'url(fonts/ShadowsIntoLight.ttf)',{ style: 'normal', weight: 700 }),
                    ];
                    fontsList.forEach(fonts => {
                        fonts.load().then(function(loadedFontFace) {
                            document.fonts.add(loadedFontFace);
                            //document.body.style.fontFamily = '"Junction Regular", Arial';
                        });
                    });
                    document.fonts.ready.then(()=>{ resolve() });
                })

 

Edited by jonforum

Share this post


Link to post
Share on other sites
4 minutes ago, themoonrat said:

I recommend using https://github.com/bramstein/fontfaceobserver to load custom fonts before creating pixi text objects

I actually already have implemented fontfaceobserver after my previous thread a month earlier when I asked about custom fonts. To me, It wouldn't make sense for the Labels to work and the Buttons to not in the same session if they use the same font. I'll post my code for that too though just in case im wrong:

Engine.prototype.loadAllFonts = function(callback){
  allFonts = this.assets.get(this.fontsKey);
  allFonts = allFonts.map(font => new FontFaceObserver(font).load());
  Promise.all(allFonts).then(callback);
};

Where allFonts is an object based on this .json file:

{
  "customFonts": [
    "Bitmgothic"
  ]
}

When I have time I'll take a look at the code example jonforum posted to see if I can implement a fix.

Share this post


Link to post
Share on other sites
26 minutes ago, MrBill said:

I actually already have implemented fontfaceobserver after my previous thread a month earlier when I asked about custom fonts. To me, It wouldn't make sense for the Labels to work and the Buttons to not in the same session if they use the same font. I'll post my code for that too though just in case im wrong:


Engine.prototype.loadAllFonts = function(callback){
  allFonts = this.assets.get(this.fontsKey);
  allFonts = allFonts.map(font => new FontFaceObserver(font).load());
  Promise.all(allFonts).then(callback);
};

i think your code missing document.fonts.add(loadedFontFace);  document.fonts.ready.then(()=>{ resolve() });

but am not pro on this subject, i remember nothing.

 

Edited by jonforum

Share this post


Link to post
Share on other sites

 

1 hour ago, MrBill said:

To me, It wouldn't make sense for the Labels to work and the Buttons to not in the same session if they use the same font

The thing with custom fonts, is that, once loaded, the first instance being used doesn't work, but after that it does.

So if you're creating text before ffo is finished, or during it finishing, then I'd totally expect to see it not working on text drawn at one time compared to text created / drawn at another time.

If you want to 'force' text to redraw, call updateText on it. But that's a brute force method rather than solving the underlying issue.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.