4

I'm working on a map project under React, using react-leaflet, and leaflet-pixi-overlay. Markers are implemented using the PIXI overlay (React 16.13.1, pixi.js 5.3.0, leaflet 1.6.0, leaflet-pixi-overlay 1.8.1).

I am struggling a bit with the PIXI documentation. I would like to use this PIXI.Texture.fromURL method (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)

However neither my VS Code environment, nor my compiled source can access this method. I am using instead PIXI.Texture.from(imageUrl), as well as PIXI.Texture.fromLoader(imageUrl). Both seem to work, but I don't get the difference between the two? The docs don't show these as being promises, yet they seem to work well with an async await?

Then, when a load fails, I don't see how to tell that things went wrong. Actually what I don't see is how to tell that things went right! If I do:

    let failed = false;
    let newTexture;
    try {
      newTexture = await PIXI.Texture.from(url);
    } catch (err) {
      console.log(`FAILED loading texture from ${url}, err=${err}`);
      failed = true;
    }
    console.log(`valid=${texture.valid}`);

Then:

  • texture.valid is always false, even when the texture loaded and displays just fine
  • no error is ever thrown when the url points to nowhere

Any pointers, is there a site with good (recent as of 2020) PIXI references? Am I missing something basic? Thanks.


Edit 07/06/2020:

Issues were largely due to both my IDE and webpack not 'seeing' that I had update pixi.js to 5.3.0, restart of both gave me access to Texture.fromURL.

The Texture.from call is a synchronous one. My understanding is that by default, it will load a 'valid' texture of 1x1 px in case of failure. Texture.fromURL was added to provide an async solution, see https://github.com/pixijs/pixi.js/issues/6514

Looks to me like Texture.fromURL still needs a bit of work, as it doesn't seem to ever return on a failed fetch (at least for relative paths, which is what I use). I see the same thing when using the following approach:

const texture = PIXI.Texture.from(url, {
  resourceOptions: { autoLoad: false }}
);
await texture.baseTexture.resource.load();

With a bad relative path, the load function never returns in my test environment.

Will59
  • 1,430
  • 1
  • 16
  • 37
  • "Looks to me like Texture.fromURL still needs a bit of work, as it doesn't seem to ever return on a failed fetch (at least for relative paths, which is what I use). I" - do you tried similar approach with "try/catch" as you see in first code snippet in my answer below? This way such errors should be catched there - and `failed` variable is set to `true` too. – domis86 Jul 08 '20 at 14:07

1 Answers1

2

Then, when a load fails, I don't see how to tell that things went wrong. Actually what I don't see is how to tell that things went right! If I do:

...

Then:

  • texture.valid is always false, even when the texture loaded and displays just fine
  • no error is ever thrown when the url points to nowhere

Ok, first thing: please use the newest version of PIXI which is now 5.3.0: https://github.com/pixijs/pixi.js/releases/tag/v5.3.0

Texture.fromUrl was added in this PR: https://github.com/pixijs/pixi.js/pull/6687/files . Please read description of this PR: https://github.com/pixijs/pixi.js/pull/6687 - user bigtimebuddy describes 3 ways to load Texture synchronously. From this you should understand why it didnt worked in your code.

Also see: https://gamedev.stackexchange.com/questions/175313/determine-when-a-pixi-texture-is-loaded-to-clone-it

About error handling, catching errors and checking if Texture is "valid": please try running following example (modified version of yours) :

    let failed = false;
    let newTexture;
    try {
        newTexture = await PIXI.Texture.fromURL('https://loremflickr.com/100/100');
        // to see how failure works comment above line and uncomment line below:
        // newTexture = await PIXI.Texture.fromURL('http://not-existing-site-0986756.com/not_existing.jpg');
    } catch (err) {
        console.log(`FAILED loading texture`);
        console.log(err);
        failed = true;
    }
    console.log('failed: ' + (failed ? 'yes' : 'no'));
    console.log(`valid=${typeof newTexture !== 'undefined' ? newTexture.valid : 'variable newTexture is undefined'}`);
    console.log(newTexture ? newTexture : 'n/a');

And lastly about method not found in IDE:

I would like to use this PIXI.Texture.fromURL method (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)

However neither my VS Code environment, nor my compiled source can access this method.

I use PhpStorm (but other IntelliJ editor should be similar - for example: WebStorm) and it finds this method:

        /**
         * Useful for loading textures via URLs. Use instead of `Texture.from` because
         * it does a better job of handling failed URLs more effectively. This also ignores
         * `PIXI.settings.STRICT_TEXTURE_CACHE`. Works for Videos, SVGs, Images.
         * @param {string} url The remote URL to load.
         * @param {object} [options] Optional options to include
         * @return {Promise<PIXI.Texture>} A Promise that resolves to a Texture.
         */
        Texture.fromURL = function (url, options) {
            var resourceOptions = Object.assign({ autoLoad: false }, options === null || options === void 0 ? void 0 : options.resourceOptions);
            var texture = Texture.from(url, Object.assign({ resourceOptions: resourceOptions }, options), false);
            var resource = texture.baseTexture.resource;
            // The texture was already loaded
            if (texture.baseTexture.valid) {
                return Promise.resolve(texture);
            }
            // Manually load the texture, this should allow users to handle load errors
            return resource.load().then(function () { return Promise.resolve(texture); });
        };

Do you use the development build of Pixi, or production one? ( https://github.com/pixijs/pixi.js/releases ).

Update 2020-07-06:

Your comment:

One thing still not clear to me though: when using an approach based on PIXI.Loader, do the sprites using a given texture get automatically refreshed once the texture has been loaded, or is there a manual refresh process required?

If you use "PIXI.Loader" approach then you can set the "load" callback - in which you should have all resources / textures already loaded. See: https://pixijs.download/dev/docs/PIXI.Loader.html

First you define which resources need to be loaded:

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

and then you define the callback:

// 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);
});

You can try this way and inside this callback you can observe that texture of each resource is valid - for example: resources.bunny.texture.valid - it should be true.

Also, as you see in that doc, you can use other more advanced features like middleware or other callbacks for error handling etc.

domis86
  • 1,227
  • 11
  • 9
  • 1
    I am using the standard React scripts. I did not re-start completely my test server when moving to pixi 5.3.0, and it looks like webpack was not using the latest version of that package. A relaunch of my server fixed this... Same for my IDE! Thanks for the PR pointer, I now understand a bit more the synchronous nature of the original calls. One thing still not clear to me though: when using an approach based on PIXI.Loader, do the sprites using a given texture get automatically refreshed once the texture has been loaded, or is there a manual refresh process required? – Will59 Jul 06 '20 at 09:20
  • 1
    @Will59 i added update to answer about PIXI.Loader - please check :) – domis86 Jul 06 '20 at 20:34