Skip to main content

v5 迁移指南

🌐 v5 Migration Guide

本文件对尝试从 v4 升级到 v5的开发者非常有用。这包括容易出错的地方以及理解为什么你的 v4 代码可能需要一些细微修改的重要背景。总体而言,我们在 v5 中尽量保持向后兼容,并在 console 中使用弃用警告。然而,有时更改可能过于重大,需要一些额外的帮助。

🌐 This document is useful for developers who are attempting to upgrading from v4 to v5. This includes gotchas and important context for understanding why your v4 code made need some subtle changes. In general, we've try to be as backward-compatible in v5 with the use of deprecation warnings in the console. There are, however, sometimes when changes are too substantial and require some additional help.

🚧 API 变更

🌐 🚧 API Changes

打造一流的 WebGL

🌐 Making WebGL First-Class

PixiJS v5 已经将 WebGL 设为一流的渲染器,而将 CanvasRenderer 设为二流的。从功能上看,与 v4 相比变化不大,但有一堆微妙的内部命名更改,可能会让一些升级到 v5 的开发者感到困惑。例如:

🌐 PixiJS v5 has made WebGL the first-class renderer and made CanvasRenderer to be second-class. Functionally, there's not much that changed from v4, but there are a bunch of subtle internal naming changes which could trip-up some developers upgrading to v5. For instance:

  • WebGLRenderer 变成 Renderer
  • renderWebGL 变成 render(在 DisplayObject、Sprite、Container 等中)
  • _renderWebGL 变为 _render(在 DisplayObject、Container 等中)

如果你创建了一个插件或项目,以前在容器上使用过 render(见 #5510),这可能会导致你的项目无法正确渲染。请考虑将你自定义的 render 重命名为其他名称。在大多数其他情况下,当你尝试调用与 WebGL 相关的类或方法时,例如 new PIXI.WebGLRenderer(),你将收到弃用警告。

🌐 If you created a plugin or project that previously used render on a Container (see #5510), this will probably cause your project to not render correctly. Please consider renaming your user-defined render to something else. In most other cases, you'll get a deprecation warning trying to invoke WebGL-related classes or methods, e.g., new PIXI.WebGLRenderer().

渲染器参数

🌐 Renderer Parameters

Renderer 构造函数中将 options 指定为第三个参数已被官方废弃(PIXI.ApplicationPIXI.autoDetectRendererPIXI.CanvasRenderer 也是如此)。在 v4 中,我们支持两个函数签名,但在 v5 中我们废弃了 width, height, options 签名。请将 widthheight 添加到 options

🌐 Specifying options as a third parameter in Renderer constructor is officially dropped (same with PIXI.Application, PIXI.autoDetectRenderer & PIXI.CanvasRenderer). In v4 we supported two function signatures, but in v5 we dropped width, height, options signature. Please add width and height to options.

const renderer = new PIXI.Renderer(800, 600, { transparent: true }); // bad
const renderer = new PIXI.Renderer({ width: 800, height: 600, transparent: true }); // good
  • 注意:在 Renderer 或 Application 构造函数选项中添加 transparent: true 可能有助于解决某些设备上的奇怪伪影,但可能会降低 FPS。它比 preserveDrawingBuffer: true 好得多。
  • 如果你需要 v4 使用 CSS 像素调整画布大小的默认行为,请在选项中添加 autoDensity: true

并非所有内容都传到了参数。即使 WebGL2 可用,要启用 WebGL1,请使用

🌐 Not everything went to params. To enable WebGL1 even if WebGL2 is available, use

PIXI.settings.PREFER_ENV = PIXI.ENV.WEBGL;

网状、扁平、绳索

🌐 Mesh, Plane, Rope

PixiJS v5 引入了一个名为 PIXI.Mesh 的新类。这允许覆盖默认着色器并能够向几何体添加更多属性。例如,你可以向顶点添加颜色。

🌐 PixiJS v5 introduces a new class called PIXI.Mesh. This allows overriding the default shader and the ability to add more attributes to geometry. For example, you can add colors to vertices.

旧的 v4 Mesh 类已从 PIXI.mesh.Mesh 移动到 PIXI.SimpleMesh,它扩展了 PIXI.Mesh

🌐 The old v4 Mesh class has moved from PIXI.mesh.Mesh to PIXI.SimpleMesh, it extends PIXI.Mesh.

PIXI.mesh.RopePIXI.mesh.PlanePIXI.mesh.NineSlicePlane 已分别转移到 PIXI.SimpleRopePIXI.SimplePlanePIXI.NineSlicePlane

如果你在 v4 中使用自定义着色器或生成的网格,你可能会受到 v5 中这些更改的影响。

🌐 If you used custom shaders or generated meshes in v4, you might be impacted by these changes in v5.

PIXI.SimpleMesh 字段 verticesuvsindices 被封装在 mesh.geometry 属性 buffers 中。例如,这是通过 mesh.uvBuffer 属性访问缓冲区的方式:

get uvBuffer()
{
return this.geometry.buffers[1];
}

indices 属性快捷方式也缺失,但你可以访问 mesh.geometry.indexBuffer 内的数据。

🌐 The indices property shortcut is also missing, but you can access the data inside mesh.geometry.indexBuffer.

你可以覆盖缓冲区数据,并通知它数据已更改,在这种情况下,缓冲区将延迟上传到 GPU。以前在 v4 中,网格有几个标志指示哪些属性需要更新,并且它们的名称让人困惑。

🌐 You can override buffer data, and notify it that data was changed, in this case buffer will be uploaded to GPU lazily. Previously in v4 mesh had several flags that indicated which attributes have to be updated and their names confused people.

图形孔

🌐 Graphics Holes

在 v4 中,Graphics 中绘制空洞的功能非常有限。这只支持非 Shape 的绘制,例如使用 lineTobezierCurveTo 等。在 v5 中,我们通过支持形状改进了空洞 API。不幸的是,没有弃用策略来支持 v4 API。例如,在 v4 中:

🌐 Drawing holes in Graphics was very limited in v4. This only supported non-Shape drawing, like using lineTo, bezierCurveTo, etc. In v5, we improved the hole API by supporting shapes. Unfortunately, there's no deprecation strategy to support the v4 API. For instance, in v4:

const graphic = new PIXI.Graphics()
.beginFill(0xff0000)
.moveTo(0, 0)
.lineTo(100, 0)
.lineTo(100, 100)
.lineTo(0, 100)
.moveTo(10, 10)
.lineTo(90, 10)
.lineTo(90, 90)
.lineTo(10, 90)
.addHole();

v4.x 的实时示例

在 v5 中,Graphics 已简化,API 从 addHole 改为 beginHoleendHole

🌐 In v5, Graphics has simplified and the API changed from addHole to beginHole and endHole.

const graphic = new PIXI.Graphics()
.beginFill(0xff0000)
.drawRect(0, 0, 100, 100)
.beginHole()
.drawCircle(50, 50, 30)
.endHole();

开发中的实时示例

过滤器填充

🌐 Filter Padding

在 v4 中,过滤器的默认填充是 4,而在 v5 中,这已更改为默认 0。当使用时,这可能会导致某些过滤器看起来损坏。要解决此问题,只需为你创建的过滤器添加一些填充即可。

🌐 In v4 filters had a default padding of 4 and in v5 this has been changed to a default of 0. This can cause some filters to look broken when used. To fix this issue simply add some padding to the filters you create.

// Glow filter from https://github.com/pixijs/pixi-filters
const filter = new PIXI.filters.GlowFilter();
filter.padding = 4;

一些滤镜,比如 BlurFilter,会自动计算填充,因此可能不需要更改。

🌐 Some filters, like BlurFilter, automatically calculate the padding so changes may not be necessary.

过滤器默认顶点着色器

🌐 Filter Default Vertex Shader

我们重新组织了所有用于坐标系变换的 uniform,并对其重命名。如果你的滤镜不再工作,请检查是否使用默认顶点着色器。在这种情况下,你可以使用旧的 v4 顶点着色器代码。

🌐 We reorganized all uniforms dedicated to coordinate system transforms, and renamed them. If your filter doesn't work anymore, check if you use default vertex shader. In that case, you can use old v4 vertex shader code.

所有更改均在 [[Creating Filters|v5-Creating-filters]] 中进行了解释

🌐 All changes are explained in [[Creating Filters|v5-Creating-filters]]

为渲染纹理启用 Mipmapping

🌐 Enable Mipmapping for RenderTexture

以前,你可能在 v4 中得到了像这样的代码(特别是如果你看过 Ivan 的评论/JSFiddle):

🌐 Previously, you may have ended up with code like this in v4 (specifically if you saw Ivan's comment/JSFiddle):

const renderer = PIXI.autoDetectRenderer();
renderer.bindTexture(baseRenderTex, false, 0);
const glTex = baseRenderTex._glTextures[renderer.CONTEXT_UID];
glTex.enableMipmap(); // this is what actually generates mipmaps in WebGL
glTex.enableLinearScaling(); // this is what tells WebGL to USE those mipmaps

在 v5 中,不再需要此代码。

🌐 In v5, this code is no longer needed.

基础纹理资源

🌐 BaseTexture Resources

v5 中的最新功能之一是我们将所有与资源相关的功能从 BaseTexture 中解耦出来。我们创建了一个名为“resources”(资源)的新系统,现在每个 BaseTexture 都有一个资源,它封装了一些特定的资源类型。例如:VideoResource、SVGResource、ImageResource、CanvasResource。将来,我们希望能够添加其他资源类型。如果之前调用过与资源相关的方法或属性,这些很可能会在 baseTexture.resource 上。

🌐 One of the newest features in v5 is that we decoupled all the asset-specific functionality from BaseTexture. We created a new system called "resources" and each BaseTexture now has a resource that wraps some specific asset type. For instance: VideoResource, SVGResource, ImageResource, CanvasResource. In the future, we hope to be able to add other resource types. If there were asset-specific methods or properties being called before, these will probably be on baseTexture.resource.

另外,我们从 BaseTexture 中移除了所有 from* 方法,所以你只需调用 BaseTexture.from 并传入任意资源。有关 from 的更多信息,请参阅 文档

🌐 Also, we removed all of the from* methods from BaseTexture, so you just can call BaseTexture.from and pass in whatever resource. Please see docs for more information about from.

const canvas = document.createElement('canvas');
const baseTexture = PIXI.BaseTexture.from(canvas);

该 API 还允许使用纯 WebGL 和 2D 上下文调用,参见 渐变示例

🌐 That API also allows to use pure WebGL and 2d context calls, see the gradient example.

BaseTexture.source

已移动到 baseTexture.resource.source,移动到与 baseTexture 对应的资源中。RenderTexture 不存在 baseTexture.resource,并且对于没有源的资源,source 也不存在。

🌐 Has been moved to baseTexture.resource.source, moved into resource corresponding to the baseTexture. baseTexture.resource does not exist for RenderTexture, and source does not exist for resources that dont have source.

图形交互

🌐 Graphics Interaction

如果你使用透明交互图形技巧,确保你为所有元素指定 alpha=0,而不是为其部分指定。PixiJS 如何处理 alpha=0 的形状被认为是未定义行为。我们可能会将其改回,但不能保证一定会如此。

🌐 If you use transparent interactive graphics trick, make sure that you use specify alpha=0 for all element, not for its parts. How PixiJS deals with shapes that have alpha=0 is considered undefined behaviour. We might change it back, but we have no guarantees about it.

graphics.beginFill(0xffffff, 0.0); //bad
graphics.alpha = 0; //good

📦 发布更改

🌐 📦 Publishing Changes

画布成为旧版

🌐 Canvas Becomes Legacy

由于 WebGL 和 WebGL2 现在是一级支持,我们已从默认的 pixi.js 包中移除了基于画布的回退。如果你需要 CanvasRenderer,你应该改用 pixi.js-legacy

🌐 Since WebGL and WebGL2 are now first-class, we have removed the canvas-based fallback from the default pixi.js package. If you need CanvasRenderer, you should switch to use pixi.js-legacy instead.

import * as PIXI from 'pixi.js';
// Will NOT return CanvasRenderer because canvas-based
// functionality was removed from "pixi.js"
const renderer = PIXI.autoDetectRenderer(); // return PIXI.Renderer or throws error

相反,使用旧包来访问画布渲染。

🌐 Instead, use the legacy bundle to have access to the canvas rendering.

import * as PIXI from 'pixi.js-legacy';
const renderer = PIXI.autoDetectRenderer(); // returns PIXI.Renderer or PIXI.CanvasRenderer

打包更改

🌐 Bundling Changes

如果你正在使用 RollupParcel 或其他打包工具将 PixiJS 添加到你的项目中,升级到 v5 时会有一些细微的变化。具体来说,全局 PIXI 对象不再自动创建。这个更改的原因有两个:1)为了提高打包工具的 tree-shaking 效果,2)出于安全考虑,保护 PIXI

🌐 If you're using Rollup, Parcel or another bundler to add PixiJS into your project there are a few subtle changes when moving to v5. Namely, the global PIXI object is no longer created automatically. This was removed from bundling for two purpose: 1) to improve tree-shaking for bundlers, and 2) for security purpose by protecting PIXI.

这不再是有效的导入方式:

🌐 This is no longer a valid way to import:

import 'pixi.js';
const renderer = PIXI.autoDetectRenderer(); // INVALID! No more global.PIXI!

相反,你应该导入为名称空间或单个元素:

🌐 Instead, you should import as a namespace or individual elements:

import * as PIXI from 'pixi.js';
const renderer = PIXI.autoDetectRenderer();

// or even better:
import { autoDetectRenderer } from 'pixi.js';
const renderer = autoDetectRenderer();

最后,一些第三方插件可能会期望 window.PIXI,所以你可能需要像这样显式地暴露全局变量,不过这 不推荐

🌐 Lastly, some 3rd-party plugins maybe expecting window.PIXI, so you might have to explicitly expose the global like this, however this is not recommended.

import * as PIXI from 'pixi.js';
window.PIXI = PIXI; // some bundlers might prefer "global" instead of "window"

Webpack

当使用 Webpack 和第三方插件,如 pixi-spine 时,你可能会在构建全局 PIXI 对象时遇到困难,从而导致运行时错误 ReferenceError: PIXI is not defined。通常可以通过使用 Webpack 全局变量填充 来解决这个问题。

🌐 When Webpack and 3rd-party plugins, like pixi-spine, you might have difficulties building the global PIXI object resulting in a runtime error ReferenceError: PIXI is not defined. Usually this can be resolved by using Webpack shimming globals.

例如,这是你的导入代码:

🌐 For instance, here's your import code:

import * as PIXI from 'pixi.js';
import 'pixi-spine'; // or other plugins that need global 'PIXI' to be defined first

在你的 webpack.config.js 中添加一个 plugins 部分,以让 Webpack 知道全局 PIXI 变量引用 pixi.js 模块。例如:

🌐 Add a plugins section to your webpack.config.js to let know Webpack that the global PIXI variable make reference to pixi.js module. For instance:

const webpack = require('webpack');

module.exports = {
entry: '...',
output: {
...
},
plugins: [
new webpack.ProvidePlugin({
PIXI: 'pixi.js'
})
]
}