加载 PIXI 纹理,处理失败

Loading PIXI textures, handling failures

我正在 React 下做一个地图项目,使用 react-leaflet 和 leaflet-pixi-overlay。标记是使用 PIXI 覆盖实现的(React 16.13.1,pixi.js 5.3.0,leaflet 1.6.0,leaflet-pixi-overlay 1.8.1)。

我对 PIXI 文档有点费劲。我想使用这个 PIXI.Texture.fromURL 方法 (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)

但是我的 VS Code 环境和编译后的源代码都无法访问此方法。 我正在使用 PIXI.Texture.from(imageUrl) 以及 PIXI.Texture.fromLoader(imageUrl)。两者似乎都有效,但我不明白两者之间的区别?文档没有将这些显示为承诺,但它们似乎与异步等待一起工作得很好?

然后,当加载失败时,我不知道如何判断出了问题。实际上,我看不到的是如何判断事情进展顺利! 如果我这样做:

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

然后:

任何指示,是否有具有良好(截至 2020 年的)PIXI 参考的网站?我错过了一些基本的东西吗?谢谢


编辑 2020 年 7 月 6 日:

问题主要是由于我的 IDE 和 webpack 而不是 'seeing' 我已经将 pixi.js 更新到 5.3.0,重新启动两者让我可以访问 Texture.fromURL.

Texture.from 调用是同步调用。我的理解是,默认情况下,它会加载 1x1 px 的 'valid' 纹理以防失败。添加 Texture.fromURL 以提供异步解决方案,请参阅 https://github.com/pixijs/pixi.js/issues/6514

在我看来 Texture.fromURL 仍然需要一些工作,因为它似乎从来没有 return 失败的获取(至少对于相对路径,这是我使用的).使用以下方法时,我看到了同样的事情:

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

由于相对路径错误,加载函数在我的测试环境中从未 returns。

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

好的,首先:请使用最新版本的 PIXI,现在是 5.3.0:https://github.com/pixijs/pixi.js/releases/tag/v5.3.0

Texture.fromUrl 已添加到此 PR 中:https://github.com/pixijs/pixi.js/pull/6687/files . Please read description of this PR: https://github.com/pixijs/pixi.js/pull/6687 - 用户 bigtimebuddy 描述了 3 种同步加载纹理的方法。从这里你应该明白为什么它在你的代码中不起作用。

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

关于错误处理、捕获错误和检查纹理是否“有效”:请尝试运行以下示例(您的修改版本):

    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');

最后关于在 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.

我使用 PhpStorm(但其他 IntelliJ 编辑器应该类似 - 例如:WebStorm)并且它找到了这个方法:

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

你用的是开发版还是生产版? ( https://github.com/pixijs/pixi.js/releases ).

2020-07-06 更新:

您的评论:

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?

如果您使用“PIXI.Loader”方法,那么您可以设置“加载”回调——您应该在其中加载所有资源/纹理。参见:https://pixijs.download/dev/docs/PIXI.Loader.html

首先定义需要加载的资源:

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

您可以尝试这种方式,在此回调中您可以观察到每个资源的纹理都是有效的 - 例如:resources.bunny.texture.valid - 它应该是真实的。

此外,正如您在该文档中看到的那样,您可以使用其他更高级的功能,如中间件或其他用于错误处理的回调等。