PixiJS v8 迁移实战指南:从 v7 到 v8 的破坏性变更清单与代码改造手册
2026/9/19 2:33:12 网站建设 项目流程

PixiJS v8 迁移实战指南:从 v7 到 v8 的破坏性变更清单与代码改造手册

【免费下载链接】pixijsThe HTML5 Creation Engine: Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.项目地址: https://gitcode.com/gh_mirrors/pi/pixijs

本指南基于 PixiJS 仓库中 v8 迁移 Skill(skills/pixijs-migration-v8/SKILL.md)与官方迁移文档(src/docs/migrations/v8.md),系统梳理从 v7 升级到 v8 时所有必须关注的破坏性变更:异步初始化、单一pixi.js包、Graphics 的"先造型后填充"范式、纹理/着色器体系重构等。读完本文,你将掌握一份可直接对照执行的迁移检查清单,能把存量 v7 代码逐项改写成符合 v8 规范、可在 WebGL/WebGPU 双后端下运行的新代码。

迁移前:先判断"要不要升"

v8 引入了 WebGPU 渲染后端,整体性能与架构有大幅提升,但破坏性变更同样显著。升级前先问自己一个问题:项目依赖的第三方 Pixi 生态库是否已经迁移到 v8?官方迁移文档列出的生态状态如下:

  • 已迁移:Filters、Sound、Gif、Storybook、UI、Open Games;
  • 迁移中:React、Spine;
  • 待迁移:Pixi layers(官方倾向直接并入 v8 核心而非单独迁移)。

若你的项目重度依赖尚未迁移的库,建议暂缓升级;纯 Pixi 项目则可以直接动手。升级顺序建议为:导入语句 → Application 初始化 → Graphics → Text → 事件 → 着色器/滤镜 → 收尾清理

快速上手:最小可运行的 v8 应用

import { Application, Graphics } from "pixi.js"; const app = new Application(); await app.init({ width: 800, height: 600 }); document.body.appendChild(app.canvas); const g = new Graphics() .rect(0, 0, 100, 100) .fill({ color: 0xff0000 }) .stroke({ width: 2, color: 0x000000 }); app.stage.addChild(g);

注意与 v7 的关键差异:new Application()不再接受配置对象、必须await app.init(...);画布挂载使用app.canvas而非app.view;Graphics 采用"先画形状、再填充/描边"的链式调用。这一点在 Application 源码 中有明确佐证:构造函数中传入 options 会触发deprecation警告("Application constructor options are deprecated, please use Application.init() instead"),而init()内部通过autoDetectRenderer异步创建渲染器。

初始化:异步化与类型参数

必须 await app.init()

v8 引入 WebGPU 渲染器后,渲染器的创建变成了异步操作,init()返回 Promise。错误写法是把 options 传给构造函数并同步使用;正确写法如下:

const app = new Application(); await app.init({ width: 800, height: 600 }); document.body.appendChild(app.canvas);

从 Application.init 实现 可以看到,它先autoDetectRenderer(options)异步创建渲染器,再依次执行已注册的 Application 插件(如 TickerPlugin、ResizePlugin、CullerPlugin)。这也是为什么app.tickerapp.renderer等属性只有在await init()之后才可用。

app.canvas 取代 app.view

app.view依然存在但会打印弃用警告(见 Application 源码),请统一改用app.canvas。传入自定义画布的方式也变为await app.init({ view: document.createElement('canvas') })

泛型参数改为 Renderer 类型

v7 中new Application<HTMLCanvasElement>()在 v8 不再正确,因为泛型描述的不再是"视图类型"而是"渲染器类型",以保证app.renderer的类型推断准确:

// WebGL 或 WebGPU(自动检测) const app = new Application<Renderer<HTMLCanvasElement>>(); // 强制 WebGL const app = new Application<WebGLRenderer<HTMLCanvasElement>>(); // 强制 WebGPU const app = new Application<WebGPURenderer<HTMLCanvasElement>>();

初始化参数速查

ApplicationOptions支持渲染、性能、自适应缩放等配置,常用项如下(完整定义见 Application 源码):

选项说明
width/height画布宽高(像素)
backgroundColor背景色,如0x1099bb
antialias是否开启抗锯齿
resolution分辨率/设备像素比,常设window.devicePixelRatio
preference渲染后端:'webgl''webgpu''canvas'或数组
powerPreferenceGPU 电源偏好,如'high-performance'
autoStart是否自动启动渲染循环
sharedTicker是否使用共享 Ticker
resizeTo/autoDensity自动缩放与 DPR 适配
skipExtensionImports是否跳过默认扩展的自动导入(自定义构建用)

导入:从 @pixi/* 子包回归单一 pixi.js 包

单一包结构

自 v5 起 PixiJS 采用多子包结构,但多版本共存容易引发内部缓存冲突。v8 回归单一包:

// v7 旧写法 import { Application } from "@pixi/app"; import { Sprite } from "@pixi/sprite"; // v8 新写法 import { Application, Sprite } from "pixi.js";

以下 v7 核心子包在任何版本下都禁止再使用(补充性生态包如@pixi/sound不受影响,可继续使用):

@pixi/accessibility@pixi/app@pixi/assets@pixi/compressed-textures@pixi/core@pixi/display@pixi/events@pixi/extensions@pixi/extract@pixi/filter-alpha@pixi/filter-blur@pixi/filter-color-matrix@pixi/filter-displacement@pixi/filter-fxaa@pixi/filter-noise@pixi/graphics@pixi/mesh@pixi/mesh-extras@pixi/mixin-cache-as-bitmap@pixi/mixin-get-child-by-name@pixi/mixin-get-global-position@pixi/particle-container@pixi/prepare@pixi/sprite@pixi/sprite-animated@pixi/sprite-tiling@pixi/spritesheet@pixi/text@pixi/text-bitmap@pixi/text-html

自定义构建与扩展导入

v8 通过"扩展(extensions)"系统为渲染器按需装配能力。默认情况下以下扩展会被自动导入:accessibilityappeventsfilterssprite-tilingtexttext-bitmaptext-htmlgraphicsmeshsprite-nine-slice

若想完全控制包体积,可设置skipExtensionImports: true并手动按需导入:

import "pixi.js/graphics"; import "pixi.js/text"; import "pixi.js/events"; import { Application } from "pixi.js"; const app = new Application(); await app.init({ skipExtensionImports: true });

从 AbstractRenderer 初始化逻辑 可以看到:skipExtensionImports === true或旧选项manageImports === false时,渲染器会跳过环境扩展加载与默认 loader 注册。注意manageImports: false自 8.1.6 起标记为@deprecated(定义见 SharedSystems.ts),一律改用skipExtensionImports: true

即便开启默认自动导入,以下扩展也必须显式手动导入:pixi.js/advanced-blend-modespixi.js/unsafe-evalpixi.js/preparepixi.js/math-extraspixi.js/ddspixi.js/ktxpixi.js/ktx2pixi.js/basis

还有一个易踩的坑:pixi.js/text-bitmap会额外注册 Assets 加载能力。如果要在渲染器初始化之前加载位图字体,必须先导入它:

import "pixi.js/text-bitmap"; import { Assets, Application } from "pixi.js"; await Assets.load("my-font.fnt"); // 未导入 text-bitmap 则此步无法加载 await new Application().init();

社区滤镜

@pixi/filter-*系列包在 v8 下不再维护,改为从pixi-filters子模块直接导入:

import { AdjustmentFilter } from "pixi-filters/adjustment"; // 而非 @pixi/filter-adjustment

Graphics:先造型、后填充(shape-then-fill)

Graphics 是 v8 改动最大的 API。"先 beginFill 再画形状"的旧流程被彻底反转——先画出形状,再对上一个形状执行fill/stroke/cut

// v7 旧写法 const g = new Graphics().beginFill(0xff0000).drawRect(50, 50, 100, 100).endFill(); // v8 新写法 const g = new Graphics().rect(50, 50, 100, 100).fill(0xff0000);

形状方法更名对照表

v7v8
drawRectrect
drawCirclecircle
drawEllipseellipse
drawPolygonpoly
drawRoundedRectroundRect
drawStarstar
drawRegularPolygonregularPoly
drawRoundedPolygonroundPoly
drawRoundedShaperoundShape
drawChamferRectchamferRect
drawFilletRectfilletRect

fill 取代 beginFill / beginTextureFill

fill接受颜色或FillStyle选项对象,同时替代了beginFillbeginTextureFill

graphics .rect(0, 0, 100, 100) .fill({ texture: Texture.WHITE, alpha: 0.5, color: 0xff0000 });

stroke 取代 lineStyle / lineTextureStyle

graphics.rect(0, 0, 100, 100).fill("blue").stroke({ width: 2, color: "white" }); // 纹理描边 graphics .rect(0, 0, 100, 100) .stroke({ texture: Texture.WHITE, width: 10, color: 0xff0000 });

lineStyle(2, 'white')lineTextureStyle({...})均告废弃。

镂空用 cut()

beginHole()/endHole()cut()取代,同样作用于前一个形状:

graphics.rect(0, 0, 100, 100).fill(0x00ff00).circle(50, 50, 20).cut();

GraphicsContext 取代 GraphicsGeometry

v8 把绘图指令抽到独立的GraphicsContext,多个Graphics可共享同一份上下文,数据复用更高效:

const context = new GraphicsContext().rect(0, 0, 100, 100).fill(0xff0000); const g1 = new Graphics(context); const g2 = new Graphics(context);

旧写法new Graphics(graphics.geometry)已失效。仓库中大量示例采用新范式,可参考 graphics_basic_shapes.ts 与 graphics_fill_stroke_gradient.ts 等示例文件的实际用法。

Text:构造器全部改为选项对象

v7 的位置参数构造(new Text('Hello', style))在 v8 一律改为单一 options 对象:

const text = new Text({ text: "Hello", style: { fontSize: 24 } }); const bmp = new BitmapText({ text: "Hello", style: { fontFamily: "MyFont" } }); const html = new HTMLText({ text: "<b>Hello</b>", style: { fontSize: 24 } });

加载位图字体前必须import 'pixi.js/text-bitmap'(见上文"自定义构建"一节)。其余受影响构造器同理:BlurFilter({ blur, quality, resolution, kernelSize })DisplacementFilter({ sprite, scale })PlaneGeometry({ width, height, verticesX, verticesY })TileSprite({ texture, width, height })等全部改为对象入参。

Sprites 与 Mesh

Texture.from 不再自动加载 URL

v8 中纹理不再自行管理资源加载,Texture.from只接受已加载的资源或已通过Assets.load注册的字符串:

await Assets.load("image.png"); // 必须先加载 const texture = Texture.from("image.png");

NineSliceSprite 取代 NineSlicePlane

const ns = new NineSliceSprite({ texture, leftWidth: 10, topHeight: 10, rightWidth: 10, bottomHeight: 10, });

Mesh 类更名 + 选项对象

  • SimpleMeshMeshSimpleSimplePlaneMeshPlaneSimpleRopeMeshRope,全部使用选项对象构造;
  • MeshGeometry由位置参数改为对象(positionsuvsindicestopology):
const geom = new MeshGeometry({ positions: vertices, uvs, indices, topology: "triangle-list", });

ParticleContainer 改用 Particle

v8 的粒子容器不再接受 Sprite 子节点,而是接收实现了IParticle接口(xyscaleXscaleYanchorXanchorYrotationcolortexture)的轻量Particle对象。粒子不进入场景图的children数组,而是存储在扁平列表particleChildren中,因此容器不再自算边界,需要你显式提供boundsArea

const container = new ParticleContainer({ boundsArea: new Rectangle(0, 0, 800, 600), }); for (let i = 0; i < 100000; i++) { const particle = new Particle(texture); container.addParticle(particle); }

由于省去了 Sprite 的冗余属性与事件,粒子渲染数量上限大幅提升。相关示例见 particle-container_basic.ts。

事件系统:eventMode 取代 interactive

eventMode / cursor

v8 默认eventMode'passive'(不接收任何事件),必须显式设为'static'(可命中测试,不做 tick 检查)或'dynamic'(可命中测试且带 tick 检查)。sprite.interactive = true仍然作为eventMode = 'static'的别名可用,但推荐使用规范写法:

sprite.eventMode = "static"; sprite.cursor = "pointer"; sprite.on("pointertap", () => { /* handle */ });

默认值'passive'在 EventSystem 源码 中有直接实现:EventSystem._defaultEventMode = options.eventMode ?? 'passive'。事件系统的完整行为可查阅 src/events/EventBoundary.ts 与事件相关 Skill(skills/pixijs-events/SKILL.md)。

Ticker 回调参数是 Ticker 实例

v8 中ticker.add的回调第一个参数从"增量时间数值"改为Ticker实例:

app.ticker.add((ticker) => { bunny.rotation += ticker.deltaTime; });

高危陷阱:旧写法app.ticker.add((dt) => { bunny.rotation += dt; })能通过编译,但dt实际是Ticker对象,参与数值运算会被强转为NaN,导致旋转值被静默污染。

updateTransform 被移除

节点不再承载渲染逻辑,updateTransform覆写模式失效。自定义每帧逻辑请改在构造器中绑定onRender

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

着色器与滤镜:{ gl, resources } 资源体系

v8 需要同时兼容 WebGL 与 WebGPU 着色器,构造方式全面重构。核心变化是:纹理不再是 uniform,而是作为顶层resources条目传入(texture.sourcetexture.style);uniform 必须显式声明类型。

Shader.from

const shader = Shader.from({ gl: { vertex: vertexSrc, fragment: fragmentSrc }, resources: { myUniforms: new UniformGroup({ uTime: { value: 0, type: "f32" } }), }, });

同时提供gpu字段(含entryPoint与 WGSL 源码)即可实现双后端。旧写法Shader.from(vertex, fragment, uniforms)已废弃。

Filter 构造

const filter = new Filter({ glProgram: GlProgram.from({ fragment, vertex }), resources: { filterUniforms: { uTime: { value: 0, type: "f32" } } }, });

旧写法new Filter(vertex, fragment, { uTime: 0 })失效。

UniformGroup 需要类型

const uniformGroup = new UniformGroup({ uTime: { value: 1, type: "f32" }, }); uniformGroup.uniforms.uTime = 100;

new UniformGroup({ uTime: 1 })这种不带type的写法不再合法。仓库中的自定义着色器示例(mesh_custom_shader_geometry、filters_custom-shader_glsl)以及 skills/pixijs-custom-rendering/SKILL.md 提供了完整的双后端着色器实战参考。

纹理:TextureSource 体系与手动更新

BaseTexture → TextureSource

v7 的BaseTexture在 v8 中不复存在,取而代之的是一组职责更单一的 TextureSource(纹理源 = 纹理设置 + 上传/使用方式):

  • TextureSource:通用纹理源,可自由渲染或上传(主要用于 RenderTexture);
  • ImageSource:承载 ImageBitmap / HTMLImageElement 等图像资源;
  • CanvasSource:承载 canvas,主要用于 canvas 渲染(WebGPU);
  • VideoSource:承载视频,自动保持 GPU 纹理与视频帧同步;
  • BufferSource:承载任意 buffer,需保证 buffer 类型与格式兼容;
  • CompressedSource:处理 GPU 压缩纹理格式。

手动创建纹理源的示例如下:

const image = new Image(); image.onload = function () { const source = new ImageSource({ resource: image }); const texture = new Texture({ source }); }; image.src = "myImage.png";

日常使用中Assets.load返回的依然是Texture,直接使用即可。

精灵不再自动响应纹理 UV 变化

出于性能考虑(频繁换纹理时事件订阅/解绑开销不可接受),v8 的 Sprite 不再订阅纹理 UV 变更事件。若修改了纹理 frame,必须依次调用texture.update()重算 UV,再调用sprite.onViewUpdate()刷新精灵显示,两者缺一不可;更新纹理源数据(如视频纹理)则仍会自动生效:

texture.frame.width = texture.frame.width / 2; texture.update(); // 先重算纹理 UV sprite.onViewUpdate(); // 再刷新精灵显示

Mipmap 手动管理

BaseTexture.mipmap更名为autoGenerateMipmaps。RenderTexture 的 mipmap 不再自动更新,需要在渲染后手动调用source.updateMipmaps()

const rt = RenderTexture.create({ width: 100, height: 100, autoGenerateMipmaps: true, }); renderer.render({ target: rt, container: scene }); rt.source.updateMipmaps();

适配器:DOMAdapter 取代 settings.ADAPTER

v8 移除了全局settings对象,环境适配改用静态类DOMAdapter。内置两个适配器:BrowserAdapter(默认)与WebWorkerAdapter(Web Worker 环境):

import { DOMAdapter, WebWorkerAdapter } from "pixi.js"; DOMAdapter.set(WebWorkerAdapter); DOMAdapter.get().createCanvas();

settings.ADAPTER = WebWorkerAdapter; settings.ADAPTER.createCanvas()的旧写法失效。浏览器环境适配器实现见 src/environment-browser/BrowserAdapter.ts,Web Worker 版本见 src/environment-webworker/WebWorkerAdapter.ts。

其他破坏性变更汇总

  • DisplayObject 被移除Container成为所有显示对象的基类,class MyObj extends DisplayObject编译失败;
  • 叶子节点不能有子节点SpriteGraphicsMeshText均为叶子节点,需要子节点时用Container包裹;
  • 属性更名(旧名保留为带警告的弃用别名):container.namecontainer.labelcontainer.cacheAsBitmap = truecontainer.cacheAsTexture(true)
  • getBounds() 返回类型变化:现在返回Bounds对象而非RectangleBounds自带.x/.y/.width/.heightgetter,基础用法不受影响;需要Rectangle实例(如调用.contains())时改用getBounds().rectangle
  • settings 对象移除:改为AbstractRenderer.defaultOptions.resolution = 1DOMAdapter.set(BrowserAdapter)(也可在init/autoDetectRenderer时直接传resolutionfailIfMajorPerformanceCaveat等选项);
  • utils 命名空间移除import { utils } from 'pixi.js'; utils.isMobile.any()import { isMobile } from 'pixi.js'; isMobile.any()
  • 文本解析器更名TextFormatbitmapFontTextParserXMLStringFormatbitmapFontXMLStringParserXMLFormatbitmapFontXMLParser
  • Assets.add 签名变化Assets.add('bunny', 'bunny.png')Assets.add({ alias: 'bunny', src: 'bunny.png' })
  • 枚举常量替换为字符串
v7v8
SCALE_MODES.NEAREST'nearest'
SCALE_MODES.LINEAR'linear'
WRAP_MODES.CLAMP'clamp-to-edge'
WRAP_MODES.REPEAT'repeat'
WRAP_MODES.MIRRORED_REPEAT'mirror-repeat'
DRAW_MODES.TRIANGLES'triangle-list'
DRAW_MODES.TRIANGLE_STRIP'triangle-strip'
DRAW_MODES.LINES'line-list'
DRAW_MODES.LINE_STRIP'line-strip'
DRAW_MODES.POINTS'point-list'
  • 剔除(Culling)改为手动:设置container.cullable = true,渲染前调用Culler.shared.cull(container, viewRect);需要模拟旧自动行为时,通过extensions.add(CullerPlugin)注册插件。相关属性还包括cullAreacullableChildren,实现见 src/culling/Culler.ts。

迁移完成度自检清单

逐项核对,全部通过即可认为迁移完成:

  • 依赖中不再存在 v7 核心@pixi/*包(补充包如@pixi/sound允许保留)
  • 所有核心@pixi/*导入已改为pixi.js
  • 所有new Application({...})已改为await app.init({...})
  • 所有 Graphics 代码采用先造型后填充模式
  • 所有构造器使用选项对象(Text、Mesh、NineSliceSprite 等)
  • Shader/Filter 代码使用{ gl, resources }模式并带类型化 uniform
  • ParticleContainer 使用Particle而非Sprite
  • Ticker 回调通过ticker.deltaTime取增量,而非把首个参数当数值
  • 事件处理使用eventMode而非interactive
  • settingsutils引用已清除
  • DisplayObject引用全部替换为Container
  • 纹理 UV 修改处调用了sprite.onViewUpdate()
  • RenderTexture 的 mipmap 代码手动调用source.updateMipmaps()
  • settings.ADAPTER已替换为DOMAdapter.set()

常见错误速查

[严重] 从废弃的 v7 核心子包导入

// 错误 import { Sprite } from "@pixi/sprite"; import { Application } from "@pixi/app"; // 正确 import { Sprite, Application } from "pixi.js";

[严重] 用 DisplayObject 作基类

// 错误 class MyObject extends DisplayObject { /* ... */ } // 正确 class MyObject extends Container { /* ... */ }

[高] 沿用旧枚举 SCALE_MODES / WRAP_MODES / DRAW_MODES

// 错误 texture.source.scaleMode = SCALE_MODES.NEAREST; // 正确 texture.source.scaleMode = 'nearest';

旧枚举可能仍作为弃用别名工作,但应全部替换为字符串值。

[高] 用 interactive = true 代替 eventMode

interactive = true依旧作为eventMode = 'static'的别名(且无弃用警告),但eventMode才是 v8 规范 API。默认值'passive'意味着不显式设置就收不到任何事件。

[高] 使用 utils 命名空间

// 错误 import { utils } from 'pixi.js'; utils.isMobile.any(); // 正确 import { isMobile } from 'pixi.js'; isMobile.any();

[高] 指望纹理 UV 变化自动更新精灵

修改texture.frame后必须调用sprite.onViewUpdate();纹理源数据更新(如视频)仍自动反映。

进一步阅读

  • 官方 v8 迁移文档:src/docs/migrations/v8.md(本文的完整权威依据)
  • 应用初始化细节:skills/pixijs-application/SKILL.md 与 Application 源码
  • Graphics 新 API:skills/pixijs-scene-graphics/SKILL.md 及 graphics_fill_stroke_gradient.ts
  • 着色器改造:skills/pixijs-custom-rendering/SKILL.md 与 mesh_custom_shader_geometry
  • 纹理与资源系统:skills/pixijs-assets/SKILL.md
  • 销毁与性能模式:skills/pixijs-performance/SKILL.md

【免费下载链接】pixijsThe HTML5 Creation Engine: Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.项目地址: https://gitcode.com/gh_mirrors/pi/pixijs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询