v7 遷移指南
首先,PixiJS v7 是個現代化版本,反映自 PixiJS 於六年前首次發佈以來生態系統的變更。瀏覽器已獲得進步,但 PixiJS 尚未真正利用某些新功能,例如 fetch
、Workers
、現代 JavaScript 語法。此版本完整保留大多數高層級 DisplayObject(例如 Sprite、Graphics、Mesh 等)。除了少數部分外,此版本對大多數使用者應影響中度到低。
👋 放棄 Internet Explorer
Microsoft 已正式結束對 IE 的支援,因此我們決定追隨。由於 IE 是 Safaring/Chrome/Firefox/Edge 和行動瀏覽器的異常值,它簡化了我們許多現代化動作。如果您需要支援 IE,請考慮使用 Babel 或其他轉譯工具。
🗑️ 移掉多重載入
我們移除了內建的多重載入,例如 requestAnimationFrame
和 Promise
。這些東西現在已廣泛應用於瀏覽器中。如果專案需要它們,開發人員應納入他們為了向後相容性而需要的多重載入。
💬 輸出 ES2020(模組)和 ES2017(瀏覽器)
歷史上,PixiJS 僅發布 ES5(沒有類別!)。新的輸出標準讓我們可以使用過去無法使用的 ES2017 功能(例如 String.prototype.startsWith
、Array.prototype.contains
等)。它不僅使程式碼更具可讀性,輸出的外觀也更漂亮。對於模組,我們會輸出 ES2020,其中包含類似空值合併運算子 (??
) 的語法。如果您的專案需要向後相容性,您可以使用 Babel 進行轉譯或多重載入處理。
🐭 以 EventSystem 取代 InteractionManager
InteractionManager 變得很複雜且難以維護。極少數核心團隊成員理解此程式碼。我們決定轉換到 FederatedEvents,它簡潔、與 DOM 更好對齊,且支援冒泡等功能。好消息是,您不應變更程式碼,因為它基本上是個直接替換。我們在 DisplayObject 中加入了 addEventListener
和 removeEventListener
API,它們與 DOM 簽章相同,可取代 on
和 off
使用。
📦 用資產替換載入器
類似地,由於傳統方法(例如 XMLHttpRequest),我們一直在想要移除載入器。這是由 resource-loader 分岔而來的,它在 PixiJS 中已存在很長一段時間。載入器的原始設計靈感主要來自 Flash/AS3,現在看來已過時。我們希望新的反覆運算能有以下幾個功能:靜態載入、使用工作人員載入、背景載入、基於承諾、更少的快取層級。以下是這項變更將如何執行的快速範例
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);
});
現在變成
import { Assets, Sprite } from 'pixi.js';
const texture = await Assets.load('path/to/assets/background.jpg');
const image = Sprite.from(texture);
🤝 放棄使用 peerDependencies
PixiJS 在每個套件中的 package.json 中大量使用 peerDependencies
。此設計選項造成 Pixi 許多問題。移除它是一種重大的變更,現在是一個良機。我們已決定完全移除 peerDependencies
,改選用 什麼都不用。這更容易安裝和升級 pixi.js
。我們正在針對使用套件組成自訂版本的「工具」進行更新。**編輯:7.2.0 版本已還原此變更,用於保持與部分基於模組的 CDN 相容。**
👂 其他變更
- 除了
pixi.js
和pixi.js-legacy
以外,所有套件的瀏覽器組建都已移除。 - 移除
Graphics.nextRoundedRectBehavior
,這是目前的預設行為 - 移除
Text.nextLineHeightBehavior
,這是目前的預設行為 - 已移除
AbstractBatchRenderer
和BatchPluginFactory
。延伸BatchRenderer
或在預設 BatchRenderer 上使用setShaderGenerator
(例如renderer.plugins.batch
) - BatchRenderer 預設安裝於
@pixi/core
中,不再需要Renderer.registerPlugin('batch', BatchRenderer)
從 @pixi/core
匯出
@pixi/core
套件現在仰賴以下套件並重新匯出它們。
@pixi/math
@pixi/contants
@pixi/utils
@pixi/runner
@pixi/settings
@pixi/ticker
雖然某些套件在直接安裝後仍能運作,但其他套件不行,因為連同 @pixi/core
一起安裝會實際匯入相同程式碼的兩個副本。這會導致錯誤,從 @pixi/settings
變更設定沒有作用,因為 @pixi/core
有該套件的自己的版本。建議您從專案中解除安裝這些套件,改用 @pixi/core
。
import { Rectangle } from '@pixi/math';
import { settings } from '@pixi/settings';
import { ALPHA_MODES } from '@pixi/constants';
import { string2hex } from '@pixi/utils';
現在變成
import { Rectangle, settings, ALPHA_MODES, utils } from '@pixi/core';
const { string2hex } = utils;
擷取和準備系統
已將擷取和準備外掛程式轉換為 Renderer「系統」。
renderer.plugins.extract
renderer.plugins.prepare
現在變成
renderer.extract
renderer.prepare
擴充元件自行安裝
擴充元件現在自行安裝,因此您應只須匯入類別即可使用。例如,在 v6 中
import { AccessibilityManager } from '@pixi/accessibility';
import { extensions } from '@pixi/core';
extensions.add(AccessibilityManager);
現在變成
import '@pixi/accessibility';
搭配事件使用 hitTest
搭配新的事件系統,變更的常見 API 之一為 `hitTest.
import {Application} from 'pixi.js';
const app = new Application();
app.renderer.plugins.interaction.hitTest({x, y});
現在變成
import {Application, EventBoundary} from 'pixi.js';
const app = new Application();
const boundary = new EventBoundary(app.stage);
boundary.hitTest(x, y);
新的非同步提取方法
下列方法現在為非同步,並會傳回一個 Promise。
CanvasExtract.base64()
CanvasExtract.image()
Extract.base64()
Extract.image()
import {Application, EventBoundary} from 'pixi.js';
const app = new Application();
const dataUri = app.renderer.extract.base64();
現在變成
import {Application, EventBoundary} from 'pixi.js';
const app = new Application();
const dataUri = await app.renderer.extract.base64();
互動移動事件
在 v7 中,PixiJS 的互動事件現在的行為與 DOM 相同。這是刻意為之,希望與開發人員熟悉的行為保持一致,但顯然影響了 pointermove
、mousemove
和 touchmove
的行為。
與 DOM 類似,移動事件現在為區域性的。這表示如果您在物件邊界以外,將不會收到移動事件。通常,您應該考慮將移動事件新增到背景或父代,而非 DisplayObject 本身。
實作範例:https://jsfiddle.net/bigtimebuddy/spnv4wm6/
已移除互動屬性處理常式
已從事件中移除基於屬性的處理常式。這項功能屬於舊的 InteractionManager。例如
sprite.pointertap = () => {
// handler the pointertap
};
現在變成
sprite.on('pointertap', () => {
// handler the pointertap
});
已移除屬性 buttonMode
屬性 buttonMode
是用於在 pointer
和 null
之間切換 cursor
屬性的方便功能。此功能現已移除。
sprite.buttonMode = true;
現在變成
sprite.cursor = 'pointer';
如果您想重新新增此功能,可以 修改 DisplayObject 的雛型
import { DisplayObject } from 'pixi.js';
Object.defineProperty(DisplayObject.prototype, 'buttonMode', {
get() { return this.cursor === 'pointer'; },
set(value) { this.cursor = value ? 'pointer' : null; },
});
☝️ 更新建議
如果您計畫將程式碼從 v6 轉移過來,建議在升級到 v7 前,先在 v6 中實作一些較重大的變更
- 更新到最新的 v6.5.x
- 切換到事件套件,做法是安裝
@pixi/events
並替換 InteractionManager。
import { InteractionManager, extensions, Application } from 'pixi.js';
import { EventSystem } from '@pixi/events';
// Uninstall interaction
extensions.remove(InteractionManager);
// Create the renderer or application
const app = new Application();
// Install events
app.renderer.addSystem(EventSystem, 'events');
- 切換到資產套件,做法是安裝
@pixi/assets
並替換 Loader。有關實作資產的更多資訊,請參閱 本指南。 - 設定
Graphics.nextRoundedRectBehavior = true
,此設定會使用圓弧,而非貝茲曲線,作為彎角半徑。 - 設定
Text.nextLineHeightBehavior = true
,此設定會預設成 DOM 類似的行為,用於行高。
🏗️ 外掛支援
外掛 | 相容性 | 相容的外掛版本 |
---|---|---|
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 | ❌ |