Skip to main content

v8 迁移指南

🌐 v8 Migration Guide

欢迎阅读 PixiJS v8 迁移指南!本文件旨在帮助你顺利将项目从 PixiJS v7 迁移到最新最强大的 PixiJS v8。请按照以下步骤操作,以确保迁移成功。

🌐 Welcome to the PixiJS v8 Migration Guide! This document is designed to help you smoothly transition your projects from PixiJS v7 to the latest and greatest PixiJS v8. Please follow these steps to ensure a successful migration.

目录

🌐 Table of Contents

  1. 介绍
  2. 重大更改
  3. 已弃用功能
  4. 资源

1. 介绍

🌐 1. Introduction

PixiJS v8 引入了若干令人兴奋的变化和改进,显著提升了渲染器的性能。虽然我们已尽力使迁移过程尽可能顺利,但一些破坏性更改是不可避免的。本指南将指导你完成将 PixiJS v7 项目迁移到 PixiJS v8 的必要步骤。

🌐 PixiJS v8 introduces several exciting changes and improvements that dramatically enhance the performance of the renderer. While we've made efforts to keep the migration process as smooth as possible, some breaking changes are inevitable. This guide will walk you through the necessary steps to migrate your PixiJS v7 project to PixiJS v8.

2. 重大变更

🌐 2. Breaking Changes

在深入迁移流程之前,让我们回顾一下 PixiJS v8 中引入的重大变更。请务必仔细关注这些变更,因为它们可能会影响你现有的代码库。

🌐 Before diving into the migration process, let's review the breaking changes introduced in PixiJS v8. Make sure to pay close attention to these changes as they may impact your existing codebase.

我应该升级吗?

🌐 Should I Upgrade?

总体来说,答案是肯定的!但目前,可能有一些原因表明最好暂时不要升级。问问自己以下问题:

🌐 Generally, the answer is yes! But currently, there may be reasons that suggest it's best not to upgrade just yet. Ask yourself the following question:

  • 你的项目是否利用了尚未迁移到 v8 的现有 Pixi 库? 我们正在努力将我们的核心库迁移到 v8,但不希望这成为使用纯 Pixi 的人的障碍。这意味着有些库暂时还没有 v8 的对应版本。如果你的情况是这样,最好暂缓迁移。

已迁移

  • 过滤器
  • 声音
  • Gif
  • 故事书
  • 用户界面
  • 开放游戏

正在迁移:

  • 反应
  • Spine(深奥版本)

待迁移:

  • Pixi 层(我们可能会将其作为一项功能直接合并到 PixiJS v8 中,而不是迁移它)

新包结构

🌐 New Package Structure

自从 5 版本以来,PixiJS 使用了独立的子包来将其代码库组织成更小的单元。然而,这种方法导致了一些问题,例如不同 PixiJS 版本的安装冲突,从而引起内部缓存的复杂情况。

🌐 Since version 5, PixiJS has utilized individual sub-packages to organize its codebase into smaller units. However, this approach led to issues, such as conflicting installations of different PixiJS versions, causing complications with internal caches.

在 v8 中,PixiJS 已经恢复为单一包结构。虽然你仍然可以导入 PixiJS 的特定部分,但你只需要安装主包。

🌐 In v8, PixiJS has reverted to a single-package structure. While you can still import specific parts of PixiJS, you only need to install the main package.

旧:

import { Application } from '@pixi/app';
import { Sprite } from '@pixi/sprite';

新:

import { Application, Sprite } from 'pixi.js';

定制构建

🌐 Custom Builds

PixiJS 使用“扩展”系统来增加渲染器功能。默认情况下,PixiJS 包含许多扩展,以提供全面的开箱体验。然而,为了完全控制功能和打包大小,你可以手动导入特定的 PixiJS 组件。

🌐 PixiJS uses an "extensions" system to add renderer functionality. By default, PixiJS includes many extensions for a comprehensive out-of-the-box experience. However, for full control over features and bundle size, you can manually import specific PixiJS components.

// imported by default
import 'pixi.js/accessibility';
import 'pixi.js/app';
import 'pixi.js/events';
import 'pixi.js/filters';
import 'pixi.js/sprite-tiling';
import 'pixi.js/text';
import 'pixi.js/text-bitmap';
import 'pixi.js/text-html';
import 'pixi.js/graphics';
import 'pixi.js/mesh';
import 'pixi.js/sprite-nine-slice';

// not added by default, everyone needs to import these manually
import 'pixi.js/advanced-blend-modes';
import 'pixi.js/unsafe-eval';
import 'pixi.js/prepare';
import 'pixi.js/math-extras';
import 'pixi.js/dds';
import 'pixi.js/ktx';
import 'pixi.js/ktx2';
import 'pixi.js/basis';

import { Application } from 'pixi.js';

const app = new Application();

await app.init({
manageImports: false, // disable importing the above extensions
});

在初始化应用时,你可以禁用自动导入功能,以防止 PixiJS 自动导入任何扩展。你需要像上面演示的那样手动导入它们。

🌐 When initializing the application, you can disable the auto-import feature, preventing PixiJS from importing any extensions automatically. You'll need to import them manually, as demonstrated above.

还应注意,pixi.js/text-bitmap 同样添加了 Assets 加载功能。因此,如果你想在初始化渲染器之前加载位图字体,你将需要导入此扩展。

🌐 It should also be noted that the pixi.js/text-bitmap, also add Assets loading functionality. Therefore if you want to load bitmap fonts BEFORE initialising the renderer, you will need to import this extension.

import 'pixi.js/text-bitmap';
import { Assets, Application } from 'pixi.js';

await Assets.load('my-font.fnt'); // If 'pixi.js/text-bitmap' is not imported, this will not load
await new Application().init();

异步初始化

🌐 Async Initialisation

PixiJS 现在需要异步初始化。随着 WebGPU 渲染器的引入,PixiJS 在使用前现在需要等待。

🌐 PixiJS will now need to be initialised asynchronously. With the introduction of the WebGPU renderer PixiJS will now need to be awaited before being used

旧:

import { Application } from 'pixi.js';

const app = new Application();

// do pixi things

新:

import { Application } from 'pixi.js';

const app = new Application();

(async () => {
await app.init({
// application options
});

// do pixi things
})();

有了这个改变,这也意味着现在可以将 ApplicationOptions 对象传递给 init 函数,而不是构造函数。

🌐 With this change it also means that the ApplicationOptions object can now be passed into the init function instead of the constructor.

** 纹理调整 **

🌐 ** Texture adjustments **

纹理结构已经被修改,以简化在 v7 中在后台变得相当混乱的情况。纹理不再知道或管理资源的加载。这需要由你或资源管理器提前完成。纹理只期望完全加载的资源。这使得管理起来容易得多,因为纹理的验证本质上可以在构建时完成,并就此结束!BaseTexture 不再存在。取而代之的是,我们现在有各种可用的 TextureSources。一个纹理源将纹理的设置与如何上传和使用该纹理结合起来。在 v8 中,有以下纹理源:

🌐 Textures structures have been modified to simplify what was becoming quite a mess behind the scenes in v7. Textures no longer know or manage loading of resources. This needs to be done upfront by you or the assets manager. Textures expect full loaded resources only. This makes things so much easier to manage as the validation of a texture can essentially be done at construction time and left at that! BaseTexture no longer exists. In stead we now have a variety of TextureSources available. A texture source combines the settings of a texture with how to upload and use that texture. In v8 there are the following texture sources:

TextureSource - 一个原生纹理,你可以渲染它或随意上传。(主要用于渲染纹理) ImageSource - 一个包含某种图片资源(例如 ImageBitmap 或 HTML 图片)的纹理源 CanvasSource - 一个包含画布的纹理源。主要用于渲染画布或渲染到画布(WebGPU) VideoSource - 一个包含视频的纹理源。负责在 GPU 上更新纹理,以确保它们保持同步。 BufferSource - 一个包含缓冲区的纹理源。其实你想做什么都可以!确保你的缓冲类型和格式兼容! CompressedSource - 一个处理压缩纹理的纹理源。用于 GPU 压缩纹理格式。

🌐 TextureSource - a vanilla texture that you can render too or upload however you wish. (used mainly by render textures) ImageSource - a texture source that contains an image resource of some kind (eg ImageBitmap or html image) CanvasSource - a canvas source that contains a canvas. Used mainly for rendering canvases or rendering to a canvas (webGPU) VideoSource - a texture source that contains a video. Takes care of updating the texture on the GPU to ensure that they stay in sync. BufferSource - a texture source that contains a buffer. What ever you want really! make sure your buffer type and format are compatible! CompressedSource - a texture source that handles compressed textures. Used by the GPU compressed texture formats.

虽然大多数时候 Assets 会返回纹理,但你可能想自己制作!更棒的是加油吧!

🌐 Whilst the majority of the time Assets will return Textures you may want to make you own! More power to ya!

要创建一个纹理源,其签名与 baseTexture 不同。例如:

🌐 To create a texture source the signature differs from baseTexture. example:


const image = new Image();

image.onload = function(){

// create a texture source
const source = new ImageSource({
resource: image,
});

// create a texture
const texture = new Texture({
source
});
}

image.src = 'myImage.png';

图形 API 大修

🌐 Graphics API Overhaul

图形 API 有一些关键更改。事实上,这可能是 v8 中变化最多的部分。我们已经在可能的地方添加了弃用,但以下是更改的概述:

🌐 There are a few key changes to the Graphics API. In fact this is probably the most changed part of v8. We have added deprecations where possible but below is the rundown of changes:

  • v8 并不是先开始填充或描边再构建形状,而是要求你先构建形状,然后再描边/填充它。Line 的术语已被 Stroke 的术语所取代

旧:

// red rect
const graphics = new Graphics().beginFill(0xff0000).drawRect(50, 50, 100, 100).endFill();

// blue rect with stroke
const graphics2 = new Graphics().lineStyle(2, 'white').beginFill('blue').circle(530, 50, 140, 100).endFill();

新:

// red rect
const graphics = new Graphics().rect(50, 50, 100, 100).fill(0xff0000);

// blue rect with stroke
const graphics2 = new Graphics().rect(50, 50, 100, 100).fill('blue').stroke({ width: 2, color: 'white' });
  • 形状函数已被重命名。每个绘图函数已简化为名称的较短版本。不过,它们的参数是相同的:
v7 API 调用v8 API 对应
drawChamferRectchamferRect
drawCirclecircle
drawEllipseellipse
drawFilletRectfilletRect
drawPolygonpoly
drawRectrect
drawRegularPolygonregularPoly
drawRoundedPolygonroundPoly
drawRoundedRectroundRect
drawRoundedShaperoundShape
drawStarstar
  • fills 函数期望 FillStyle 选项或颜色,而不是一串参数。这也替换了 beginTextureFill

旧:

const rect = new Graphics()
.beginTextureFill({ texture: Texture.WHITE, alpha: 0.5, color: 0xff0000 })
.drawRect(0, 0, 100, 100)
.endFill()
.beginFill(0xffff00, 0.5)
.drawRect(100, 0, 100, 100)
.endFill();

新:

const rect = new Graphics()
.rect(0, 0, 100, 100)
.fill({ texture: Texture.WHITE, alpha: 0.5, color: 0xff0000 })
.rect(100, 0, 100, 100)
.fill({ color: 0xffff00, alpha: 0.5 });
  • 斯托克斯函数期望 StrokeStyle 选项或一种颜色,而不是一串参数。这也替换了 lineTextureStyle 旧:
  const rect = new Graphics()
.lineTextureStyle({texture:Texture.WHITE, width:10, color:0xFF0000})
.drawRect(0, 0, 100, 100)
.endFill()
.lineStyle(2, 0xFEEB77);
.drawRect(100, 0, 100, 100)
.endFill();

新:

const rect = new Graphics()
.rect(0, 0, 100, 100)
.stroke({ texture: Texture.WHITE, width: 10, color: 0xff0000 })
.rect(100, 0, 100, 100)
.stroke({ color: 0xfeeb77, width: 2 });
  • holes 现在使用一个新的 cut 函数。与 strokefill 一样,cut 作用于之前的形状。 旧版:
const rectAndHole = new Graphics()
.beginFill(0x00ff00)
.drawRect(0, 0, 100, 100)
.beginHole()
.drawCircle(50, 50, 20)
.endHole()
.endFill();

新:

const rectAndHole = new Graphics().rect(0, 0, 100, 100).fill(0x00ff00).circle(50, 50, 20).cut();
  • GraphicsGeometry 已被 GraphicsContext 替换,这使得共享 Graphics 数据更加高效。

旧:

const rect = new Graphics().beginFill(0xff0000).drawRect(50, 50, 100, 100).endFill();

const geometry = rect.geometry;

const secondRect = new Graphics(geometry);

新:

const context = new GraphicsContext().rect(50, 50, 100, 100).fill(0xff0000);

const rect = new Graphics(context);
const secondRect = new Graphics(context);

着色器更改

🌐 Shader changes

由于我们现在需要同时支持 WebGL 和 WebGPU 着色器,它们的构建方式已经进行了调整以考虑这一点。你会注意到的主要区别(这是针对着色器的一般情况)是,纹理不再被视为 uniform(即它们不能包含在 uniform 组中)。相反,我们引入了资源的概念。资源可以是几种东西,包括:

🌐 As we now need to accommodate both WebGL and WebGPU shaders, the way they are constructed has been tweaked to take this into account. The main differences you will notice (this is for shaders in general) is that Textures are no longer considered uniforms (as in they cannot be included in a uniform group). Instead we have the concept of resources. A resource can be a few things including:

  • TextureSource - 源纹理 myTexture.source
  • TextureStyle - 一种纹理风格 myTexture.style
  • UniformGroup - 一组基于数字的制服 myUniforms = new UniformGroup({})
  • BufferResource - 被视为统一组的缓冲区(高级)

现在创建一个仅 webgl 的着色器如下所示:

🌐 creating a webgl only shader now looks like this:

old

const shader = PIXI.Shader.from(vertex, fragment, uniforms);

new

仅 WebGL

🌐 just WebGL

const shader = Shader.from({
gl: { vertex, fragment },
resources, // resource used from above including uniform groups
});

WebGL 和 WebGPU

🌐 WebGL and WebGPU

const shader = Shader.from({
gl: { vertex, fragment },
gpu: {
vertex: {
entryPoint: 'mainVert',
source,
},
fragment: {
entryPoint: 'mainFrag',
source,
},
},
resources, // resource used from above including uniform groups
});

制服的构造方式也略有不同。在创建它们时,你现在需要提供你希望它成为的变量类型。

🌐 Uniforms are also constructed in a slightly different way. When creating them, you now provide the type of variable you want it to be.

old

const uniformGroup = new UniformGroup({
uTime: 1,
});

uniformGroup.uniforms.uTime = 100;

new

const uniformGroup = new UniformGroup({
uTime:{value:1, type:'f32',
});

uniformGroup.uniforms.uTime = 100; // still accessed the same!

要充分了解此新设置,最好的方法是查看 Mesh 和 Shader 示例:

🌐 The best way to play and fully and get to know this new setup please check out the Mesh and Shader examples:

: v7 示例 : v8 示例

过滤器

🌐 Filters

过滤器的工作原理几乎完全相同,除非你正在构建一个自定义的过滤器。如果是这种情况,上面提到的着色器更改需要被考虑在内。

🌐 Filters work almost exactly the same, unless you are constructing a custom one. If this is the case, the shader changes mentioned above need to taken into account.

old

const filter = new Filter(vertex, fragment, {
uTime: 0.0,
});

new

const filter = new Filter({
glProgram: GlProgram.from({
fragment,
vertex,
}),
resources: {
timeUniforms: {
uTime: { value: 0.0, type: 'f32' },
},
},
});

: v7 示例 : v8 示例

如果你正在使用 社区过滤器,请注意 @pixi/filter-* 包在 v8 版本中不再维护,然而,你可以直接从 pixi-filters 包作为子模块导入。

🌐 If you're using the community filters, note that the @pixi/filter-* packages are no-longer maintained for v8, however, you can import directly from the pixi-filters package as sub-modules.

*old

import { AdjustmentFilter } from '@pixi/filter-adjustment';

*new

import { AdjustmentFilter } from 'pixi-filters/adjustment';

ParticleContainer

ParticleContainer 在 v8 中已被重新设计,以允许比以前更多的粒子。你应该注意以下几个关键变化:

ParticleContainer 不再接受精灵作为其子元素。相反,它需要一个 Particle 类(或实现了 IParticle 接口的对象),该接口如下所示:

🌐 A ParticleContainer no longer accepts sprites as its children. Instead, it requires a Particle class (or an object that implements the IParticle interface), which follows this interface:

export interface IParticle
{
x: number;
y: number;
scaleX: number;
scaleY: number;
anchorX: number;
anchorY: number;
rotation: number;
color: number;
texture: Texture;
}

这种变化的原因是精灵带有许多额外的属性和事件,而在处理大量粒子时,这些通常是不必要的。这种方法明确消除了我们在v7中遇到的任何模糊性,例如“为什么我的精灵不能与滤镜一起工作?”或“为什么我不能在精灵中嵌套子对象?”这样更可预测。此外,由于粒子的轻量特性,这意味着我们可以渲染更多的粒子!

🌐 The reason for this change is that sprites come with many extra properties and events that are generally unnecessary when dealing with large numbers of particles. This approach explicitly removes any ambiguity we had in v7, such as "Why doesn't my sprite work with filters?" or "Why can't I nest children in my sprites?" It’s a bit more predictable. Additionally, due to the lightweight nature of particles, this means we can render far more of them!

因此,没有丢失任何功能 - 只是 API 调整,性能大幅提升!

🌐 So, no functionality is lost—just an API tweak with a massive performance boost!

粒子也不会存储在 ParticleContainerchildren 数组中,因为从技术上讲,粒子并不是场景图的一部分(出于性能原因)。相反,它们存储在一个名为 particleChildren 的平面列表中,该列表是 ParticleContainer 类的一部分。你可以直接修改这个数组以获得更高的速度,或者你可以使用 addParticleremoveParticle 方法来管理你的粒子。

🌐 Particles are also not stored in the children array of the ParticleContainer, as particles are not technically part of the scene graph (for performance reasons). Instead, they are stored in a flat list called particleChildren, which is part of the ParticleContainer class. You can modify this array directly for extra speed, or you can use the addParticle and removeParticle methods to manage your particles.

另一个优化是 ParticleContainer 不会计算它自己的边界,因为这样做会抵消我们所创造的性能提升!相反,你需要在初始化 ParticleContainer 时提供一个 boundsArea

🌐 Another optimization is that ParticleContainer does not calculate its own bounds, as doing so would negate the performance gains we've created! Instead, it's up to you to provide a boundsArea when initializing the ParticleContainer.


const container = new ParticleContainer();

for (let i = 0; i < 100000; i++) {
const particle = new Sprite(texture);
container.addChild(particle);
}

const container = new ParticleContainer();

for (let i = 0; i < 100000; i++) {
const particle = new Particle(texture);
container.addParticle(particle);
}

具有边界区域

🌐 with a bounds area

const container = new ParticleContainer({
boundsArea: new Rectangle(0, 0, 500, 500),
});

其他重大变化

🌐 Other Breaking Changes

  • DisplayObject 已被移除。Container 现在是所有 PixiJS 对象的基类。

  • updateTransform 已被移除,因为节点不再包含任何渲染逻辑

    我们确实认识到许多人使用此功能在每一帧执行自定义逻辑,因此我们添加了一个新的 onRender 函数,可以用于这个目的。

    旧:

    class MySprite extends Sprite {
    constructor() {
    super();
    this.updateTransform();
    }

    updateTransform() {
    super.updateTransform();
    // do custom logic
    }
    }

    新:

    class MySprite extends Sprite {
    constructor() {
    super();
    this.onRender = this._onRender.bind(this);
    }

    _onRender() {
    // do custom logic
    }
    }
  • Mipmap 生成更改

    • BaseTexture mipmap 属性已被重命名为 autoGenerateMipmaps
    • RenderTextures 的 mipmaps 已经过调整,因此开发者需要负责更新它们的 mipmaps。生成 mipmaps 可能代价很高,并且由于我们处理纹理的新响应式方式,我们不希望在不需要时意外生成 mipmaps。
const myRenderTexture = RenderTexture.create({ width: 100, height: 100, autoGenerateMipmaps: true });

// do some rendering..
renderer.render({ target: myRenderTexture, container: scene });

// now refresh mipmaps when you are ready
myRenderTexture.source.updateMipmaps();
  • 由于 PixiJS 内部处理方式的改变,精灵不再会在纹理的 UV 被修改时收到通知。最佳做法是创建纹理后不要修改其 UV。最好提前准备好纹理(它们的创建和存储成本很低)。
  • 有时,你可能想使用一种特殊的技术来动画化 UV。在最后这种情况下,你将负责更新精灵(值得注意的是,它可能会自动更新——但由于新的优化,这将无法保证)。然而,更新源数据(例如视频纹理)将始终立即反映出来。
const texture = await Assets.load('bunny.png');
const sprite = new Sprite(texture);

texture.frame.width = texture.frame.width / 2;
texture.update();

// guarantees the texture changes will be reflected on the sprite
sprite.onViewUpdate();

// alternatively you can hooke into the sprites event
texture.on('update', () => {
sprite.onViewUpdate;
});

在精灵的纹理发生变化时添加和移除事件的行为导致了无法接受的性能下降,尤其是在交换许多纹理时(想象一下有大量关键帧纹理交换的射击游戏)。这就是为什么我们现在将这一责任留给用户的原因。

🌐 The act of adding and removing the event when a sprite's texture was changed led to an unacceptable performance drop, especially when swapping many textures (imagine shooting games with lots of keyframe textures swapping). This is why we now leave that responsibility to the user.

  • 新的容器剔除方法

    在这个版本的 PixiJS 中,我们改变了容器上 cullable 属性的工作方式。之前在渲染循环中,裁剪是自动为你完成的。然而,我们已经将此逻辑移出,并为用户提供了自行控制裁剪发生时间的能力。

    通过此更改,我们添加了一些新属性:

    • cullable - 容器是否可以被剔除
    • cullArea - 将使用一个剔除区域来代替容器的边界
    • cullableChildren - 是否可以清除容器的子元素。这可以帮助优化大型场景

    新:

    const container = new Container();
    const view = new Rectangle(0, 0, 800, 600);

    container.cullable = true;
    container.cullArea = new Rectangle(0, 0, 400, 400);
    container.cullableChildren = false;

    Culler.shared.cull(myContainer, view);
    renderer.render(myContainer);

    还有一个 CullerPlugin 可以用来自动在每一帧调用 Culler.shared.cull,如果你想模拟旧的行为。

    import { extensions, CullerPlugin } from 'pixi.js';
    extensions.add(CullerPlugin);
  • 重命名了几个网格类

    • 已将 SimpleMesh 重命名为 MeshSimple
    • 已将 SimplePlane 重命名为 MeshPlane
    • 已将 SimpleRope 重命名为 MeshRope
  • Assets 的弃用已被移除

    旧:

    import { Assets } from 'pixi.js';

    Assets.add('bunny', 'bunny.png');

    新:

    import { Assets } from 'pixi.js';

    Assets.add({ alias: 'bunny', src: 'bunny.png' });
  • settings 对象已被移除

    旧:

    import { settings, BrowserAdapter } from 'pixi.js';

    settings.RESOLUTION = 1;
    settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
    settings.ADAPTER = BrowserAdapter;

    新:

    import { AbstractRenderer, DOMAdapter, BrowserAdapter } from 'pixi.js';

    // Can also be passed into the renderer directly e.g `autoDetectRenderer({resolution: 1})`
    AbstractRenderer.defaultOptions.resolution = 1;

    // Can also be passed into the renderer directly e.g `autoDetectRenderer({failIfMajorPerformanceCaveat: false})`
    AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat = false;

    // See below for more information about changes to the adapter
    DOMAdapter.set(BrowserAdapter);
  • 适配器和 Web Worker 更改

    • settings.ADAPTER 已被移除并被 DOMAdapter 替代

      • DOMAdapter 是一个静态类,可用于设置整个应用的适配器
      • PixiJS 内置了两个适配器 BrowserAdapterWebWorkerAdapter
        • BrowserAdapter 是默认适配器,在浏览器中运行时使用
        • WebWorkerAdapter 在 web 工作者中运行时使用

      旧:

      import { settings, WebWorkerAdapter } from 'pixi.js';

      settings.ADAPTER = WebWorkerAdapter;
      settings.ADAPTER.createCanvas();

      新:

      import { DOMAdapter, WebWorkerAdapter } from 'pixi.js';

      DOMAdapter.set(WebWorkerAdapter);
      DOMAdapter.get().createCanvas();
  • 应用类型现在接受 Renderer 而不是 view,由 @Zyie 在 https://github.com/pixijs/pixijs/pull/9740 提交

    这是为了让 app.renderer 能被正确输入

    旧:

    const app = new Application<HTMLCanvasElement>();

    新:

    // WebGL or WebGPU renderer
    const app = new Application<Renderer<HTMLCanvasElement>>();
    // WebGL specific renderer
    const app = new Application<WebGLRenderer<HTMLCanvasElement>>();
    // WebGPU specific renderer
    const app = new Application<WebGPURenderer<HTMLCanvasElement>>();
  • Texture.from 不再从 URL 加载纹理。

    使用 Texture.from 时,你需要传入一个源,例如 CanvasSource/ImageSource/VideoSource,或者一个资源,例如 HTMLImageElement/HTMLCanvasElement/HTMLVideoElement,或者一个通过 Assets.load 加载的字符串

    旧:

    import { Texture } from 'pixi.js';

    const texture = Texture.from('https://i.imgur.com/IaUrttj.png');

    新:

    import { Assets, Texture } from 'pixi.js';

    await Assets.load('https://i.imgur.com/IaUrttj.png');
    const texture = Texture.from('https://i.imgur.com/IaUrttj.png');
  • Ticker 的回调现在将传递 Ticker 实例,而不是时间增量。这是为了允许对使用的时间单位有更多控制。

    旧:

    Ticker.shared.add((dt) => {
    bunny.rotation += dt;
    });

    新:

    Ticker.shared.add((ticker) => {
    bunny.rotation += ticker.deltaTime;
    });
  • 文本解析器已重命名

    • TextFormat -> bitmapFontTextParser
    • XMLStringFormat -> bitmapFontXMLStringParser
    • XMLFormat -> bitmapFontXMLParser
  • 默认的 eventMode 现在是 passive 而不是 auto

  • utils 已被移除。所有功能都可以直接导入使用。

    旧:

    import { utils } from 'pixi.js';

    utils.isMobile.any();

    新:

    import { isMobile } from 'pixi.js';

    isMobile.any();
  • container.getBounds() 现在返回一个 Bounds 对象,而不是 Rectangle 对象。你可以改用 container.getBounds().rectangle 来访问矩形。

    旧:

    const bounds = container.getBounds();

    新:

    const bounds = container.getBounds().rectangle;
  • container.cacheAsBitmap 已被替换为 container.cacheAsTexture()。它们的功能相同,只是我们更改了 cacheAsTexture 的名称,因为位图的术语与 PixiJS 并不真正相关。

    旧:

    container.cacheAsBitmap = true;

    新:

    container.cacheAsTexture(true);

3. 已弃用的功能

🌐 3. Deprecated Features

PixiJS v7 的某些功能在 v8 中已被弃用。虽然它们仍然可以使用,但建议更新代码以使用新的替代方案。有关应替换的具体内容,请参阅弃用功能部分。

🌐 Certain features from PixiJS v7 have been deprecated in v8. While they will still work, it's recommended to update your code to use the new alternatives. Refer to the deprecated features section for details on what to replace them with.

  • 叶节点不再允许子节点

    只有 Containers 可以有子节点。这意味着 SpriteMeshGraphics 等不能再有子节点。

    要复制旧的行为,你可以创建一个 Container 并将叶子节点添加到其中。

    旧:

    const sprite = new Sprite();
    const spriteChild = new Sprite();
    sprite.addChild(spriteChild);

    新:

    const container = new Container();
    const sprite = new Sprite();
    const spriteChild = new Sprite();

    container.addChild(sprite);
    container.addChild(spriteChild);
  • Application.view 被替换为 Application.canvas

    旧:

    const app = new Application({ view: document.createElement('canvas') });
    document.body.appendChild(app.view);

    新:

    const app = new Application();
    await app.init({ view: document.createElement('canvas') });
    document.body.appendChild(app.canvas);
  • NineSlicePlane 已重命名为 NineSliceSprite

  • SCALE_MODESScaleMode 字符串替换

    • SCALE_MODES.NEAREST -> 'nearest',
    • SCALE_MODES.LINEAR -> 'linear',
  • WRAP_MODESWrapMode 字符串替换

    • WRAP_MODES.CLAMP -> 'clamp-to-edge',
    • WRAP_MODES.REPEAT -> 'repeat',
    • WRAP_MODES.MIRRORED_REPEAT -> 'mirror-repeat',
  • DRAW_MODESTopology 字符串替换

    • DRAW_MODES.POINTS -> 'point-list',
    • DRAW_MODES.LINES -> 'line-list',
    • DRAW_MODES.LINE_STRIP -> 'line-strip',
    • DRAW_MODES.TRIANGLES -> 'triangle-list',
    • DRAW_MODES.TRIANGLE_STRIP -> 'triangle-strip',
  • 构造函数已很大程度上更改为接受对象而不是多个参数

    旧:

    const blurFilter = new BlurFilter(8, 4, 1, 5);
    const displacementFilter = new DisplacementFilter(sprite, 5);
    const meshGeometry = new MeshGeometry(vertices, uvs, index);
    const mesh = new Mesh(geometry, shader, state, drawMode);
    const plane = new PlaneGeometry(width, height, segWidth, segHeight);
    const nineSlicePlane = new NineSlicePlane(texture, leftWidth, topHeight, rightWidth, bottomHeight);
    const tileSprite = new TileSprite(texture, width, height);
    const text = new Text('Hello World', style);
    const bitmapText = new BitmapText('Hello World', style);
    const htmlText = new HTMLText('Hello World', style);

    新:

    const blurFilter = new BlurFilter({
    blur: 8,
    quality: 4,
    resolution: 1,
    kernelSize: 5,
    });
    const displacementFilter = new DisplacementFilter({
    sprite,
    scale: 5,
    });
    const meshGeometry = new MeshGeometry({
    positions: vertices,
    uvs,
    indices: index,
    topology: 'triangle-list';
    shrinkBuffersToFit: boolean;
    });
    const mesh = new Mesh({
    geometry
    shader
    texture
    });
    const plane = new PlaneGeometry({
    width,
    height,
    verticesX: segWidth,
    verticesY: segHeight,
    });
    const nineSliceSprite = new NineSliceSprite({
    texture,
    leftWidth,
    topHeight,
    rightWidth,
    bottomHeight,
    });
    const tileSprite = new TileSprite({
    texture,
    width,
    height,
    });
    const text = new Text({
    text: 'Hello World',
    style,
    });
    const bitmapText = new BitmapText({
    text:'Hello World',
    style,
    });
    const htmlText = new HTMLText({
    text:'Hello World',
    style,
    });
  • container.name 现在是 container.label

4. 资源

🌐 4. Resources