PixiJS v7 迁移指南:从 v6 升级的完整变更解析与实战手册
2026/9/19 23:09:03 网站建设 项目流程

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 并没有充分利用诸如fetchWorkers、现代 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,典型代表是requestAnimationFramePromise。这些能力如今在浏览器中已广泛可用,不再需要库本身兜底。

迁移策略很简单:如果项目运行环境确实缺失这些能力,开发者应自行引入所需的 polyfill以保持向后兼容,而不是依赖 PixiJS 提供。

💬 输出标准升级:ES2020(modules)与 ES2017(browser)

历史上 PixiJS 只发布 ES5 代码(这意味着连 class 都不能使用!)。v7 采用了新的输出标准:

  • modules 输出 ES2020,可以使用如空值合并运算符(nullish coalescing,??)等语法;
  • browser 输出 ES2017,允许使用String.prototype.startsWithArray.prototype.contains等此前无法使用的 API。

这不仅让源码更易读,产物也更干净。如果项目自身需要向后兼容,同样可以通过 Babel 转译或 polyfill 处理。

🐭 事件系统:InteractionManager 替换为 EventSystem

旧版 InteractionManager 日益复杂、难以维护,核心团队中几乎没人能完全读懂它。v7 将其替换为基于FederatedEvents(联邦事件)的新体系,设计上更简洁、与 DOM 更对齐,并且原生支持事件冒泡(bubbling)

好消息是:对大多数代码而言这是近乎**即插即用(drop-in replacement)**的替换,你通常不需要改动代码。

addEventListener / removeEventListener

v7 在 DisplayObject 上新增了addEventListenerremoveEventListener方法,其签名与 DOM 完全一致,可替代onoff使用。从当前仓库的 src/events/FederatedEventTarget.ts 可以看到,addEventListener明确"寻求与 DOM 的addEventListener兼容,支持 options 参数(如 capture 阶段监听)",甚至支持传入带handleEvent方法的对象作为监听器。

事件传播:捕获、目标、冒泡三阶段

v7 将事件传播对齐 DOM 模型,这一点在当前仓库的EventBoundary实现中体现得淋漓尽致。src/events/EventBoundary.ts 的propagate方法依次执行:

  1. 捕获阶段(CAPTURING_PHASE):从根目标向事件目标逐层下行;
  2. 目标阶段(AT_TARGET):在事件目标上触发;
  3. 冒泡阶段(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 靠拢是有意为之的设计,但这确实会影响pointermovemousemovetouchmove的语义:

和 DOM 一样,move 事件现在变为局部(local)事件。也就是说,当指针位于对象边界之外时,你将收不到该对象的 move 事件。一般而言,建议把 move 事件监听挂在stage 或父容器上,而不是 DisplayObject 本身。

属性式事件处理器被移除

旧 InteractionManager 支持属性式(property-based)处理器,v7 中已全部移除:

// v6 写法(已移除) sprite.pointertap = () => { // 处理 pointertap };
// v7 写法 sprite.on('pointertap', () => { // 处理 pointertap });

属性buttonMode被移除

buttonMode曾是切换cursor属性(在pointernull之间)的便捷开关,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.jspixi.js-legacy之外的所有包均不再提供浏览器构建;
  • Graphics.nextRoundedRectBehavior被移除:该行为现为默认行为;
  • Text.nextLineHeightBehavior被移除:该行为现为默认行为;
  • AbstractBatchRendererBatchPluginFactory被移除:请改为继承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.WebGLSystemExtensionType.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>,并支持通过formatquality等选项控制导出格式与质量。

☝️ 升级建议:先在 v6 中完成铺垫

官方建议在从 v6 升级到 v7 之前,先在 v6.5.x 上完成一些"大动作"的迁移,以降低一次性升级的风险:

  1. 升级到最新的 v6.5.x
  2. 切换到 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');
  1. 切换到 Assets 包:安装@pixi/assets,用 Assets 替换 Loader。实现细节可参考仓库内的 Assets 指南;
  2. 设置Graphics.nextRoundedRectBehavior = true:让圆角矩形使用**圆弧(arcs)**而非贝塞尔曲线(bezier curves)计算圆角半径——这正是 v7 的默认行为;
  3. 设置Text.nextLineHeightBehavior = true:让行高采用 DOM 风格行为——同样是 v7 的默认行为。

在 v6 阶段提前完成上述切换,v6 → v7 的升级就会平滑很多,因为事件与资源加载这两块最大的 API 变化已经被提前消化。

🏗️ 插件兼容性

v7 发布时对生态插件的兼容状态如下表。升级前请确认你使用的插件版本满足要求,其中PixiJS AnimatePixiJS Tilemap当时尚不兼容 v7:

插件兼容性支持的插件版本
PixiJS Soundv5.0.0+
PixiJS HTMLTextv3.0.0+
PixiJS Filtersv5.0.0+
PixiJS GIFv2.0.0+
PixiJS Spinev4.0.0+
PixiJS Particle Emitterv5.0.8+
PixiJS Animate
PixiJS Layersv2.0.0+
PixiJS Lightsv4.0.0+
PixiJS Graphics Smoothv1.0.0+
PixiJS Tilemap

小结:一张迁移速查表

主题v6 写法v7 写法
事件命中测试renderer.plugins.interaction.hitTest({ x, y })new EventBoundary(stage).hitTest(x, y)
事件属性处理器sprite.pointertap = fnsprite.on('pointertap', fn)
光标样式sprite.buttonMode = truesprite.cursor = 'pointer'
资源加载loader.add(...); loader.load(cb)const texture = await Assets.load(url)
Extract/Preparerenderer.plugins.extract/renderer.plugins.preparerenderer.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),仅供参考

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

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

立即咨询