0
\$\begingroup\$

I'm in the latest PIXI v5, where my texture is made like let texture = PIXI.Texture.from(TEXTURE_URL).

The texture isn't loaded synchronously- Pixi just covers this up. That would be fine but when I try to apply a frame, the following error is thrown because the texture has no dimensions because it isn't loaded yet. I have no way of determining whether it's loaded or not!

Error: Texture Error: frame does not fit inside the base Texture dimensions: X: 8 + 8 = 16 > 0 and Y: 0 + 8 = 8 > 0 

How can I get a promise for when a Pixi texture is loaded or clone it anyway?

\$\endgroup\$
1
\$\begingroup\$

Use PIXI.Loader, here's an example from that link:

const loader = PIXI.Loader.shared; // PixiJS exposes a premade instance for you to use.

// Chainable `add` to enqueue a resource
loader.add('bunny', 'data/bunny.png')
      .add('spaceship', 'assets/spritesheet.json');
loader.add('scoreFont', 'assets/score.fnt');

// The `load` method loads the queue of resources, and calls the passed in callback called once all
// resources have loaded.
loader.load((loader, resources) => {
    // resources is an object where the key is the name of the resource loaded and the value is the resource object.
    // They have a couple default properties:
    // - `url`: The URL that the resource was loaded from
    // - `error`: The error that happened when trying to load (if any)
    // - `data`: The raw data that was loaded
    // also may contain other properties based on the middleware that runs.
    sprites.bunny = new PIXI.TilingSprite(resources.bunny.texture);
    sprites.spaceship = new PIXI.TilingSprite(resources.spaceship.texture);
    sprites.scoreFont = new PIXI.TilingSprite(resources.scoreFont.texture);
});

For your convenience, these functions are also available:

// throughout the process multiple signals can be dispatched.
loader.onProgress.add(() => {}); // called once per loaded/errored file
loader.onError.add(() => {}); // called once per errored file
loader.onLoad.add(() => {}); // called once per loaded file
loader.onComplete.add(() => {}); // called once when the queued resources all load.

This way, when you call new Texture(...) with one of those assets, it will be initialised instantly, and its dimensions will be available to you.

\$\endgroup\$
0
\$\begingroup\$

One solution is to wait (and keep polling) to see whether the texture dimensions have changed.

  async function() {
    await new Promise(resolve => {
      let interval = setInterval(() => {
        if(texture.orig.width !== 0) {
          resolve();
        }
      }, 20);
    });

    // do things here, texture is loaded
  }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.