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. 介绍

    ¥Introduction

  2. 重大变化

    ¥Breaking Changes

  3. 已弃用的功能

    ¥Deprecated Features

  4. 资源

    ¥Resources

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. 重大变化

¥ 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 对应库。如果你是这种情况,最好推迟迁移。

    ¥Does your project leverage existing Pixi libraries that have not yet been migrated to v8? We are working hard to migrate our key libraries to v8 but did not want this to be a blocker for those who are using pure Pixi. This means some libraries will not have a v8 counterpart just yet. It's best to hold off on migration if this is the case for you.

已迁移

¥Migrated

  • 过滤器

    ¥Filters

  • 声音

    ¥Sound

  • Gif

  • 故事书

    ¥Storybook

  • UI

    • 开放游戏

      ¥Open Games

正在迁移:

¥Migrating Right Now:

  • React

  • Spine(深奥版本)

    ¥Spine (esoteric version)

待迁移:

¥To Be Migrated:

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

    ¥Pixi layers (rather than migrating this, we will likely incorporate it directly into PixiJS v8 as a feature)

新的封装结构

¥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.

老的:

¥Old:

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

新的:

¥New:

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

定制构建

¥Custom Builds

PixiJS 使用 "extensions" 系统来添加渲染器功能。默认情况下,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

老的:

¥Old:

import { Application } from 'pixi.js';

const app = new Application();

// do pixi things

新的:

¥New:

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 不再存在。相反,我们现在有各种可用的 TextureSource。纹理源将纹理的设置与如何上传和使用该纹理相结合。在 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 eon 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 的术语

    ¥Instead of beginning a fill or a stroke and then building a shape, v8 asks you to build your shape and then stroke / fill it. The terminology of Line has been replaced with the terminology of Stroke

老的:

¥Old:

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

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

新的:

¥New:

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


// blur rect with stroke
const graphics2 = new Graphics()
.rect(50, 50, 100, 100)
.fill('blue')
.stroke({width:2, color:'white'});
  • 形状函数已重命名。每个绘图函数都被简化为其名称的较短版本。但它们具有相同的参数:

    ¥Shape functions have been renamed. Each drawing function has been simplified into a shorter version of its name. They have the same parameters though:

v7 API 调用v8 API 等效项
drawChamferRectchamferRect
drawCirclecircle
drawEllipseellipse
drawFilletRectfilletRect
drawPolygonpoly
drawRectrect
drawRegularPolygonregularPoly
drawRoundedPolygonroundPoly
drawRoundedRectroundRect
drawRoundedShaperoundShape
drawStarstar
  • 填充函数需要 FillStyle 个选项或颜色,而不是参数字符串。这也取代了 beginTextureFill

    ¥fills functions expect FillStyle options or a color, rather than a string of parameters. This also replaces beginTextureFill

老的:

¥Old:

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

新的:

¥New:

  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});
  • stokes 函数需要 StrokeStyle 个选项或颜色,而不是一串参数。这也取代了旧的 lineTextureStyle

    ¥stokes functions expect StrokeStyle options or a color, rather than a string of parameters. This also replaces lineTextureStyle Old:

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

新的:

¥New:

  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});
  • 孔现在使用新的 cut 函数。与 strokefill 一样,cut 作用于先前的形状。老的:

    ¥holes now make use of a new cut function. As with stroke and fill, cut acts on the previous shape. Old:

  const rectAndHole = new Graphics()
.beginFill(0x00FF00)
.drawRect(0, 0, 100, 100)
.beginHole()
.drawCircle(50, 50, 20)
.endHole()
.endFill();

新的:

¥New:

  const rectAndHole = new Graphics()
.rect(0, 0, 100, 100)
.fill(0x00FF00)
.circle(50, 50, 20)
.cut();
  • GraphicsGeometry 已替换为 GraphicsContext,这样可以更有效地共享 Graphics 数据。

    ¥GraphicsGeometry has been replaced with GraphicsContext this allows for sharing of Graphics data more efficiently.

老的:

¥Old:

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

const geometry = rect.geometry;

const secondRect = new Graphics(geometry);

新的:

¥New:

  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 着色器,因此它们的构造方式已经过调整以考虑到这一点。你会注意到的主要区别(这通常适用于着色器)是纹理不再被视为统一的(因为它们不能包含在统一组中)。相反,我们有资源的概念。资源可以是以下几种东西:

¥As we now need to accommodate both WebGL and WebGPU shaders, the wey 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

    ¥TextureSource - A source texture myTexture.source

  • TextureStyle - 纹理样式 myTexture.style

    ¥TextureStyle - A texture style myTexture.style

  • UniformGroup - 基于数字的统一 myUniforms = new UniformGroup({}) 的集合

    ¥UniformGroup - A collection of number based uniforms myUniforms = new UniformGroup({})

  • BufferResource - 被视为统一组的缓冲区(高级)

    ¥BufferResource - A buffer that is treated as a uniform group (advanced)

现在创建一个仅 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 示例

¥old: v7 example new: v8 example

过滤器

¥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 示例

¥old: v7 example new: v8 example

如果你使用的是 社区过滤器,请注意 @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 has been reworked in v8 to allow for far more particles than before. There are a few key changes you should be aware of:

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.


OLD

const container = new ParticleContainer();

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

NEW

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 对象的基类。

    ¥DisplayObject has been removed. Container is now the base class for all PixiJS objects.

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

    ¥updateTransform has been removed as nodes no longer contain any rendering logic

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

    ¥We do recognise that many people used this function to do custom logic every frame, so we have added a new onRender function that can be used for this purpose.

    老的:

    ¥Old:

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

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

    新的:

    ¥New:

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

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

    ¥Mipmap generation changes

    • BaseTexture mipmap 属性已重命名为 autoGenerateMipmaps

      ¥The BaseTexture mipmap property has been renamed to autoGenerateMipmaps.

    • RenderTextures 的 Mipmap 已进行调整,以便开发者负责更新它们的 Mipmap。Mipmap 的生成可能会很昂贵,并且由于我们处理纹理的新反应方式,我们不希望在不需要时意外生成 mipmap。

      ¥Mipmaps for RenderTextures have been adjusted so that developer is responsible for updating them mipmaps. Mipmap generation can be expensive, and due to the new reactive way we handle textures we do not want to accidentally generate mipmaps when they are not required.

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 创建后不要对其进行修改。最好准备好纹理(它们的创建和存储成本低廉)。

    ¥Due to the new way PixiJS handles things internally, sprites no longer get notified if a texture's UVs have been modified. The best practice is not to modify texture UVs once they have been created. It's best to have textures ready to go (they are inexpensive to create and store).

  • 有时,你可能想要采用一种特殊的技术来动画 UV。在最后一个实例中,你将负责更新精灵(值得注意的是,它可能会自动更新 - 但由于新的优化,这将无法得到保证)。然而,更新源数据(例如视频纹理)总是会立即反映。

    ¥Sometimes, you might want to employ a special technique that animates the UVs. In this last instance, you will be responsible for updating the sprite (it's worth noting that it may update automatically - but due to the new optimizations, this will not be guaranteed). Updating the source data (e.g., a video texture) will, however, always be reflected immediately.

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.

  • 新的容器剔除方法

    ¥New Container culling approach

    在这个版本的 PixiJS 中,我们更改了 cullable 属性在容器上的工作方式。以前,剔除是在渲染循环期间自动为你完成的。然而,我们已经移除了这个逻辑,并为用户提供了自己控制何时发生剔除的能力。

    ¥With this version of PixiJS we have changed how the cullable property works on containers. Previously culling was done for you automatically during the render loop. However, we have moved this logic out and provided users the ability to control when culling happens themselves.

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

    ¥With this change we have added a couple of new properties:

    • cullable - 容器是否可以被剔除

      ¥cullable - Whether or not the container can be culled

    • cullArea - 将使用一个剔除区域来代替容器的边界

      ¥cullArea - A cull area that will be used instead of the bounds of the container

    • cullableChildren - 容器子项是否可以被剔除。这可以帮助优化大场景

      ¥cullableChildren - Whether or not the containers children can be culled. This can help optimise large scenes

    新的:

    ¥New:

    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

    ¥There is also a CullerPlugin that can be used to automatically call Culler.shared.cull every frame if you want to simulate the old behaviour.

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

    ¥Renamed several mesh classes

    • 重命名为 SimpleMesh -> MeshSimple

      ¥renamed SimpleMesh -> MeshSimple

    • 重命名为 SimplePlane -> MeshPlane

      ¥renamed SimplePlane -> MeshPlane

    • 重命名为 SimpleRope -> MeshRope

      ¥renamed SimpleRope -> MeshRope

  • 删除了对 Assets 的弃用

    ¥Deprecations for Assets removed

    老的:

    ¥Old:

    import { Assets } from 'pixi.js';

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

    新的:

    ¥New:

    import { Assets } from 'pixi.js';

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

    ¥settings object has been removed

    老的:

    ¥Old:

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

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

    新的:

    ¥New:

    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 更改

    ¥Adapter and Web Worker Changes

    • settings.ADAPTER 已被删除并替换为 DOMAdapter

      ¥settings.ADAPTER has been removed and replaced with DOMAdapter

      • DOMAdapter 是一个静态类,可用于设置整个应用的适配器

        ¥DOMAdapter is a static class that can be used to set the adapter for the entire application

      • PixiJS 有两个内置的适配器 BrowserAdapterWebWorkerAdapter

        ¥PixiJS has two adapters built in BrowserAdapter and WebWorkerAdapter

        • BrowserAdapter 是默认适配器,在浏览器中运行时使用

          ¥BrowserAdapter is the default adapter and is used when running in the browser

        • 在 Web Worker 中运行时使用 WebWorkerAdapter

          ¥WebWorkerAdapter is used when running in a web worker

      老的:

      ¥Old:

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

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

      新的:

      ¥New:

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

      DOMAdapter.set(WebWorkerAdapter);
      DOMAdapter.get().createCanvas();
  • 应用类型现在接受 Renderer 而不是 https://github.com/pixijs/pixijs/pull/9740 中 @Zyie 的视图

    ¥Application type now accepts Renderer instead of view by @Zyie in https://github.com/pixijs/pixijs/pull/9740

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

    ¥This is to allow app.renderer to be typed correctly

    老的:

    ¥Old:

    const app = new Application<HTMLCanvasElement>();

    新的:

    ¥New:

    // 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 no longer will load a texture from a URL.

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

    ¥When using Texture.from you will need to pass in a source such as CanvasSource/ImageSource/VideoSource or a resource such as HTMLImageElement/HTMLCanvasElement/HTMLVideoElement or a string that has been loaded through Assets.load

    老的:

    ¥Old:

    import { Texture } from 'pixi.js';

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

    新的:

    ¥New:

    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 实例而不是增量时间。这是为了更好地控制使用的时间单位。

    ¥The Ticker's callback will now pass the Ticker instance instead of the delta time. This is to allow for more control over what unit of time is used.

    老的:

    ¥Old:

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

    新的:

    ¥New:

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

    ¥Text parsers have been renamed

    • TextFormat -> bitmapFontTextParser

    • XMLStringFormat -> bitmapFontXMLStringParser

    • XMLFormat -> bitmapFontXMLParser

  • 默认 eventMode 现在是 passive 而不是 auto

    ¥The default eventMode is now passive instead of auto

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

    ¥utils has been removed. All the functions are available as direct imports.

    老的:

    ¥Old:

    import { utils } from 'pixi.js';

    utils.isMobile.any();

    新的:

    ¥New:

    import { isMobile } from 'pixi.js';

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

    ¥container.getBounds() now returns a Bounds object instead of a Rectangle object. You can access the rectangle by using container.getBounds().rectangle instead.

    老的:

    ¥Old:

    const bounds = container.getBounds();

    新的:

    ¥New:

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

    ¥container.cacheAsBitmap has been replaced with container.cacheAsTexture(). They do the same things, except we changed the name cacheAsTexture as the Bitmap terminology is not really relevant to PixiJS.

    老的:

    ¥Old:

    container.cacheAsBitmap = true;

    新的:

    ¥New:

    container.cacheAsTexture(true);

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.

  • 叶节点不再允许子节点

    ¥Leaf nodes no longer allow children

    只有 Containers 可以生子级。这意味着 SpriteMeshGraphics 等不能再生育子级。

    ¥Only Containers can have children. This means that Sprite, Mesh, Graphics etc can no longer have children.

    要复制旧行为,你可以创建 Container 并向其添加叶节点。

    ¥To replicate the old behaviour you can create a Container and add the leaf nodes to it.

    老的:

    ¥Old:

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

    新的:

    ¥New:

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

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

    ¥Application.view replaced with Application.canvas

    老的:

    ¥Old:

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

    新的:

    ¥New:

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

    ¥NineSlicePlane renamed to NineSliceSprite

  • SCALE_MODES 替换为 ScaleMode 字符串

    ¥SCALE_MODES replaced with ScaleMode strings

    • SCALE_MODES.NEAREST -> 'nearest',

    • SCALE_MODES.LINEAR -> 'linear',

  • WRAP_MODES 替换为 WrapMode 字符串

    ¥WRAP_MODES replaced with WrapMode strings

    • WRAP_MODES.CLAMP -> 'clamp-to-edge',

    • WRAP_MODES.REPEAT -> 'repeat',

    • WRAP_MODES.MIRRORED_REPEAT -> 'mirror-repeat',

  • DRAW_MODES 替换为 Topology 字符串

    ¥DRAW_MODES replaced with Topology strings

    • 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',

  • 构造函数已很大程度上更改为接受对象而不是多个参数

    ¥Constructors have largely been changed to accept objects instead of multiple arguments

    老的:

    ¥Old:

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

    新的:

    ¥New:

    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

    ¥container.name is now container.label

4. 资源

¥ Resources