PixiJS v7 迁移指南:从 v6 升级的完整变更解析与实战手册
【免费下载链接】pixijsThe HTML5 Creation Engine: Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.项目地址: https://gitcode.com/gh_mirrors/pi/pixijs
本指南基于 v7 迁移文档,系统梳理 PixiJS 从 v6 升级到 v7 的所有破坏性变更与行为调整:包括事件系统从 InteractionManager 切换到 EventSystem、资源加载从 Loader 切换到 Assets、包结构与导出体系的重构,以及各类 API 的替换写法。读完本文,你将能够对照旧代码逐项完成迁移,并理解 v7 各项"现代化"决策背后的设计动机,为后续升级到 v8 打下基础。
总览:v7 是一次"现代化"发布
PixiJS v7 是一版以现代化为核心的发布。自 PixiJS 首次发布以来已经超过六年,浏览器生态发生了巨大变化,但 PixiJS 并没有充分利用诸如fetch、Workers、现代 JavaScript 语法等新能力。v7 正是补齐这些能力的一次系统性重构:它保留了 Sprite、Graphics、Mesh 等高层 DisplayObject 的绝大部分 API,因此对大多数用户而言,本次升级的影响等级为中低(medium to low)。
从当前仓库源码看,v7 奠定的这些机制在后续版本中得到了延续与深化:例如事件系统中用于命中测试的EventBoundary类至今仍保留在 src/events/EventBoundary.ts 中,资产加载体系则进一步演进为 src/assets/Assets.ts 中基于 Promise、支持后台加载与 Bundle 的完整系统。仓库的 migrations 目录 下同时保存了 v5、v6、v7、v8 四份迁移文档,读者可以对照阅读,理解各版本间的演进脉络。
👋 放弃 Internet Explorer 支持
Microsoft 官方已终止对 IE 的支持,因此 v7 决定跟进放弃。这一决定极大简化了现代化改造,因为 IE 曾是 Safari/Chrome/Firefox/Edge 与移动浏览器阵营之外的"异类"(outlier)。
如果你的项目仍然必须支持 IE,官方建议使用Babel或其他转译(trans-piling)工具自行处理兼容。v7 之后的源码本身不再为 IE 特化。
🗑️ 移除内置 Polyfills
v7 移除了随包分发的 polyfill,典型代表是requestAnimationFrame和Promise。这些能力如今在浏览器中已广泛可用,不再需要库本身兜底。
迁移策略很简单:如果项目运行环境确实缺失这些能力,开发者应自行引入所需的 polyfill以保持向后兼容,而不是依赖 PixiJS 提供。
💬 输出标准升级:ES2020(modules)与 ES2017(browser)
历史上 PixiJS 只发布 ES5 代码(这意味着连 class 都不能使用!)。v7 采用了新的输出标准:
- modules 输出 ES2020,可以使用如空值合并运算符(nullish coalescing,
??)等语法; - browser 输出 ES2017,允许使用
String.prototype.startsWith、Array.prototype.contains等此前无法使用的 API。
这不仅让源码更易读,产物也更干净。如果项目自身需要向后兼容,同样可以通过 Babel 转译或 polyfill 处理。
🐭 事件系统:InteractionManager 替换为 EventSystem
旧版 InteractionManager 日益复杂、难以维护,核心团队中几乎没人能完全读懂它。v7 将其替换为基于FederatedEvents(联邦事件)的新体系,设计上更简洁、与 DOM 更对齐,并且原生支持事件冒泡(bubbling)。
好消息是:对大多数代码而言这是近乎**即插即用(drop-in replacement)**的替换,你通常不需要改动代码。
addEventListener / removeEventListener
v7 在 DisplayObject 上新增了addEventListener与removeEventListener方法,其签名与 DOM 完全一致,可替代on和off使用。从当前仓库的 src/events/FederatedEventTarget.ts 可以看到,addEventListener明确"寻求与 DOM 的addEventListener兼容,支持 options 参数(如 capture 阶段监听)",甚至支持传入带handleEvent方法的对象作为监听器。
事件传播:捕获、目标、冒泡三阶段
v7 将事件传播对齐 DOM 模型,这一点在当前仓库的EventBoundary实现中体现得淋漓尽致。src/events/EventBoundary.ts 的propagate方法依次执行:
- 捕获阶段(CAPTURING_PHASE):从根目标向事件目标逐层下行;
- 目标阶段(AT_TARGET):在事件目标上触发;
- 冒泡阶段(BUBBLING_PHASE):从事件目标逐层回传到根。
并支持propagationStopped(停止传播)与propagationImmediatelyStopped(立即停止传播)两种中断机制。这套实现与浏览器 DOM 事件模型高度一致,是 v7 "FederatedEvents 更对齐 DOM" 这一设计目标最直接的源码证据。
hitTest 的迁移
v7 中受影响较大的常用 API 之一是hitTest。旧写法通过renderer.plugins.interaction调用:
import { Application } from 'pixi.js'; const app = new Application(); app.renderer.plugins.interaction.hitTest({ x, y });新写法改为创建EventBoundary并传入(x, y)两个独立参数:
import { Application, EventBoundary } from 'pixi.js'; const app = new Application(); const boundary = new EventBoundary(app.stage); boundary.hitTest(x, y);该签名至今仍在使用:当前仓库中 EventBoundary.hitTest(x, y) 接收两个坐标参数,返回命中的Container(若未命中则返回 null),并可通过hitTestMoveRecursive/hitTestRecursive分别处理移动事件与普通事件的命中路径。
Move 事件变为"局部"事件
v7 的交互事件行为向 DOM 靠拢是有意为之的设计,但这确实会影响pointermove、mousemove、touchmove的语义:
和 DOM 一样,move 事件现在变为局部(local)事件。也就是说,当指针位于对象边界之外时,你将收不到该对象的 move 事件。一般而言,建议把 move 事件监听挂在stage 或父容器上,而不是 DisplayObject 本身。
属性式事件处理器被移除
旧 InteractionManager 支持属性式(property-based)处理器,v7 中已全部移除:
// v6 写法(已移除) sprite.pointertap = () => { // 处理 pointertap };// v7 写法 sprite.on('pointertap', () => { // 处理 pointertap });属性buttonMode被移除
buttonMode曾是切换cursor属性(在pointer与null之间)的便捷开关,v7 中已删除:
// v6 写法(已移除) sprite.buttonMode = true;// v7 写法 sprite.cursor = 'pointer';如果你希望恢复这一便利,可以通过 patch DisplayObject 原型的方式重新实现:
import { DisplayObject } from 'pixi.js'; Object.defineProperty(DisplayObject.prototype, 'buttonMode', { get() { return this.cursor === 'pointer'; }, set(value) { this.cursor = value ? 'pointer' : null; }, });📦 资源加载:Loader 替换为 Assets
Loader 因其遗留技术(如 XMLHttpRequest)而遭到淘汰——它源自与 PixiJS 相伴多年的 resource-loader,其最初设计灵感来自 Flash/AS3 时代的思路,如今已显过时。v7 用全新的Assets系统取而代之,设计目标包括:
- 静态加载(static loading);
- 支持Worker加载;
- 后台加载(background loading);
- 基于Promise;
- 更少的缓存层级。
下面是典型的迁移对照。v6 的 Loader 写法:
import { Loader, Sprite } from 'pixi.js'; const loader = new Loader(); loader.add('background', 'path/to/assets/background.jpg'); loader.load((loader, resources) => { const image = Sprite.from(resources.background.texture); });v7 的 Assets 写法:
import { Assets, Sprite } from 'pixi.js'; const texture = await Assets.load('path/to/assets/background.jpg'); const image = Sprite.from(texture);新 API 的核心优势一目了然:不再需要手动注册资源名与回调,Assets.load直接返回 Promise,加载结果即纹理本身,可以直接交给Sprite.from使用。
Assets 在后续版本中的演进(源码佐证)
Assets 系统在当前仓库中已成为 PixiJS 资源管理的唯一入口。src/assets/Assets.ts 中可以看到它的完整能力面:
Assets.load(urls, onProgress)支持加载单个资源或资源数组,并可通过 ProgressCallback 回调获取 0.0~1.0 的进度值;Assets.loadBundle(bundleId, onProgress)支持按 Bundle(资源包)成组加载,Bundle 内资产可用别名(alias)单独加载,例如Sprite.from('background');Assets.init({ basePath, manifest, texturePreference, bundleIdentifier, preferences })支持配置 CDN 基路径、加载 manifest 清单、按设备能力选择纹理格式(如['avif', 'webp', 'png'])与分辨率等(参见 AssetInitOptions 的完整注释示例);- 配套的
BackgroundLoader支持后台加载,Cache统一管理缓存。
关于 Assets 的完整使用指南,可参考仓库内的 Assets 文档。
🤝 放弃 peerDependencies(并于 7.2.0 回滚)
PixiJS 曾重度依赖各包package.json中的peerDependencies,这一设计选择给 Pixi 带来了许多问题。由于移除它属于破坏性变更,v7 发布时正是动手的好时机——官方决定彻底移除peerDependencies,改为"什么都不依赖",这让pixi.js的安装与升级都变得简单许多。
重要修订(Edit):自 7.2.0 起,该变更已被回滚,以保持与部分基于模块的 CDN 的兼容性。升级到 7.2.0+ 的用户不受此变更影响;若你的项目介于 7.0.0~7.1.x 之间,则需了解当时 peerDependencies 已被移除这一背景。
👂 其他变更
v7 还包含以下值得注意的变更:
- 浏览器构建被移除:除
pixi.js与pixi.js-legacy之外的所有包均不再提供浏览器构建; Graphics.nextRoundedRectBehavior被移除:该行为现为默认行为;Text.nextLineHeightBehavior被移除:该行为现为默认行为;AbstractBatchRenderer与BatchPluginFactory被移除:请改为继承BatchRenderer,或在默认的 BatchRenderer(如renderer.plugins.batch)上使用setShaderGenerator;- BatchRenderer 默认安装:
@pixi/core已默认安装 BatchRenderer,不再需要手动执行Renderer.registerPlugin('batch', BatchRenderer)。
Exports from@pixi/core
@pixi/core包现在依赖并重新导出以下包:
@pixi/math@pixi/constants@pixi/utils@pixi/runner@pixi/settings@pixi/ticker
需要特别警惕:部分包即使单独安装后仍能"工作",但另一些则不行——因为与@pixi/core并排安装,你实际上会导入同一份代码的两个副本。这会导致诸如"修改@pixi/settings的配置不生效"之类的诡异问题(因为@pixi/core持有的是自己的那份副本)。官方建议:从项目中卸载这些包,统一改用@pixi/core。
迁移对照:
// v6 写法(多个独立包) import { Rectangle } from '@pixi/math'; import { settings } from '@pixi/settings'; import { ALPHA_MODES } from '@pixi/constants'; import { string2hex } from '@pixi/utils';// v7 写法(统一从 @pixi/core 导入) import { Rectangle, settings, ALPHA_MODES, utils } from '@pixi/core'; const { string2hex } = utils;Extract 与 Prepare 系统化
Extract 和 Prepare 插件被转换为 Renderer 的 "systems"(系统):
// v6 写法(已移除) renderer.plugins.extract; renderer.plugins.prepare;// v7 写法 renderer.extract; renderer.prepare;这一"插件 → 系统"的架构演进在后续版本中继续深化:当前仓库中提取功能已由 ExtractSystem 承担,是渲染器共享系统(shared system)之一。
Extensions 自安装
v7 起扩展(Extensions)改为自我安装(self-install):只需导入类即可完成注册,无需手动extensions.add。
v6 写法:
import { AccessibilityManager } from '@pixi/accessibility'; import { extensions } from '@pixi/core'; extensions.add(AccessibilityManager);v7 写法:
import '@pixi/accessibility';这一机制延续至今:当前仓库中 AccessibilitySystem 通过静态extension属性声明自己的类型(同时注册为ExtensionType.WebGLSystem与ExtensionType.WebGPUSystem)与名称('accessibility'),导入模块即完成注册,渲染器初始化时会根据类型自动装配。
新的异步 Extract 方法
以下方法现在改为异步并返回 Promise:
CanvasExtract.base64()CanvasExtract.image()Extract.base64()Extract.image()
// v6 写法(同步) import { Application } from 'pixi.js'; const app = new Application(); const dataUri = app.renderer.extract.base64();// v7 写法(异步) import { Application } from 'pixi.js'; const app = new Application(); const dataUri = await app.renderer.extract.base64();该异步签名在后续版本中保持不变:当前仓库 ExtractSystem.image() 返回Promise<ImageLike>,内部先调用await this.base64(options)获取 data URI 再创建图片对象;ExtractSystem.base64() 同样返回Promise<string>,并支持通过format、quality等选项控制导出格式与质量。
☝️ 升级建议:先在 v6 中完成铺垫
官方建议在从 v6 升级到 v7 之前,先在 v6.5.x 上完成一些"大动作"的迁移,以降低一次性升级的风险:
- 升级到最新的 v6.5.x;
- 切换到 Events 包:安装
@pixi/events,用 EventSystem 替换 InteractionManager:
import { InteractionManager, extensions, Application } from 'pixi.js'; import { EventSystem } from '@pixi/events'; // 卸载 interaction extensions.remove(InteractionManager); // 创建渲染器或应用 const app = new Application(); // 安装 events app.renderer.addSystem(EventSystem, 'events');- 切换到 Assets 包:安装
@pixi/assets,用 Assets 替换 Loader。实现细节可参考仓库内的 Assets 指南; - 设置
Graphics.nextRoundedRectBehavior = true:让圆角矩形使用**圆弧(arcs)**而非贝塞尔曲线(bezier curves)计算圆角半径——这正是 v7 的默认行为; - 设置
Text.nextLineHeightBehavior = true:让行高采用 DOM 风格行为——同样是 v7 的默认行为。
在 v6 阶段提前完成上述切换,v6 → v7 的升级就会平滑很多,因为事件与资源加载这两块最大的 API 变化已经被提前消化。
🏗️ 插件兼容性
v7 发布时对生态插件的兼容状态如下表。升级前请确认你使用的插件版本满足要求,其中PixiJS Animate与PixiJS Tilemap当时尚不兼容 v7:
| 插件 | 兼容性 | 支持的插件版本 |
|---|---|---|
| PixiJS Sound | ✅ | v5.0.0+ |
| PixiJS HTMLText | ✅ | v3.0.0+ |
| PixiJS Filters | ✅ | v5.0.0+ |
| PixiJS GIF | ✅ | v2.0.0+ |
| PixiJS Spine | ✅ | v4.0.0+ |
| PixiJS Particle Emitter | ✅ | v5.0.8+ |
| PixiJS Animate | ❌ | — |
| PixiJS Layers | ✅ | v2.0.0+ |
| PixiJS Lights | ✅ | v4.0.0+ |
| PixiJS Graphics Smooth | ✅ | v1.0.0+ |
| PixiJS Tilemap | ❌ | — |
小结:一张迁移速查表
| 主题 | v6 写法 | v7 写法 |
|---|---|---|
| 事件命中测试 | renderer.plugins.interaction.hitTest({ x, y }) | new EventBoundary(stage).hitTest(x, y) |
| 事件属性处理器 | sprite.pointertap = fn | sprite.on('pointertap', fn) |
| 光标样式 | sprite.buttonMode = true | sprite.cursor = 'pointer' |
| 资源加载 | loader.add(...); loader.load(cb) | const texture = await Assets.load(url) |
| Extract/Prepare | renderer.plugins.extract/renderer.plugins.prepare | renderer.extract/renderer.prepare |
| 扩展注册 | extensions.add(X) | import 'pkg'(自安装) |
| 导出截屏 | renderer.extract.base64()(同步) | await renderer.extract.base64()(异步) |
总而言之,v7 通过放弃旧浏览器、引入现代 JavaScript 能力、重构事件与资源两大核心系统,为 PixiJS 后续的架构演进(如 v8 的渲染管线重构)铺平了道路。对照本文的迁移清单逐项处理,即可将存量 v6 项目平稳升级至 v7。
【免费下载链接】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),仅供参考