【问题标题】:Loading PIXI textures, handling failures加载 PIXI 纹理,处理失败
【发布时间】:2020-07-03 17:37:35
【问题描述】:

我正在使用 react-leaflet 和 Leaflet-pixi-overlay 在 React 下开发一个地图项目。标记是使用 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}`);

然后:

  • texture.valid 始终为 false,即使纹理已加载并显示正常
  • 当 url 指向无处时不会引发错误

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


编辑 07/06/2020:

问题主要是由于我的 IDE 和 webpack 都没有“看到”我已将 pixi.js 更新到 5.3.0,重新启动两者后我可以访问 Texture.fromURL。

Texture.from 调用是同步调用。我的理解是,默认情况下,如果失败,它将加载 1x1 像素的“有效”纹理。添加 Texture.fromURL 以提供异步解决方案,请参阅https://github.com/pixijs/pixi.js/issues/6514

在我看来,Texture.fromURL 仍然需要一些工作,因为它似乎永远不会在失败的提取中返回(至少对于我使用的相对路径而言)。使用以下方法时,我看到了同样的情况:

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

如果相对路径不好,加载函数在我的测试环境中永远不会返回。

【问题讨论】:

  • "在我看来,Texture.fromURL 仍然需要一些工作,因为它似乎永远不会在失败的提取中返回(至少对于我使用的相对路径而言)。我” - 您是否尝试过与“try/catch”类似的方法,正如您在下面我的答案中的第一个代码 sn-p 中看到的那样?这种方式应该在那里捕获此类错误 - 并且 failed 变量也设置为 true

标签: reactjs pixi.js react-leaflet


【解决方案1】:

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

...

然后:

  • texture.valid 始终为 false,即使纹理已加载并显示正常
  • 当 url 指向无处时不会引发错误

好的,第一件事:请使用最新版本的 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。请阅读此 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 中找不到的方法:

我想使用这个 PIXI.Texture.fromURL 方法 (http://pixijs.download/release/docs/PIXI.Texture.html#.fromURL)

但是我的 VS Code 环境和我的编译源都不能访问这个方法。

我使用 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); });
        };

您使用 Pixi 的开发版本还是生产版本? (https://github.com/pixijs/pixi.js/releases)。

2020-07-06 更新:

您的评论:

我仍然不清楚一件事:当使用基于 PIXI.Loader 的方法时,使用给定纹理的精灵会在纹理加载后自动刷新,还是需要手动刷新过程?

如果您使用“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 - 它应该是真的。

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

【讨论】:

  • 我使用的是标准的 React 脚本。迁移到 pixi 5.3.0 时,我没有完全重新启动我的测试服务器,看起来 webpack 没有使用该软件包的最新版本。重新启动我的服务器解决了这个问题......我的 IDE 也一样!感谢 PR 指针,我现在对原始调用的同步性质有了更多的了解。但我仍然不清楚一件事:当使用基于 PIXI.Loader 的方法时,使用给定纹理的精灵会在纹理加载后自动刷新,还是需要手动刷新过程?
  • @Will59 我添加了更新以回答有关 PIXI.Loader - 请检查:)
猜你喜欢
  • 2013-07-28
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多