Pixi是一個超快的2D渲染引擎,通過Javascript和Html技術建立動畫或管理互動式影像,從而製作遊戲或應用。
專案地址:https://github.com/pixijs/pixi.js
API 地址:https://pixijs.download/dev/docs/index.html
中文教程地址:https://github.com/Zainking/learningPixi
問題
一個簡單的demo,主要是通過pixi.js繪製一張圖片並展示在頁面中。通過觀察工作管理員->效能->GPU模組可以發現,頁面一直在渲染,導致GPU持續被佔用。本來的目的只是想展示一張靜態圖片即可,並不要求實時重新整理。換句話說,就是如何實現pixi.js
只在需要的時候進行渲染。
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<script type="text/javascript">
let Application = PIXI.Application,
loader = PIXI.loader,
resources = PIXI.loader.resources,
Sprite = PIXI.Sprite;
//Create a Pixi Application
let app = new Application({
width: 1000,
height: 800,
});
document.body.appendChild(app.view);
loader.add("img/wall5.jpg").load(setup);
function setup() {
let img = new Sprite(resources["img/wall5.jpg"].texture);
app.stage.addChild(img);
}
</script>
解決方案
在檢視了pixi.js的原始碼後發現,它的持續渲染還是通過requestAnimationFrame
實現的。下面簡單分析下實現過程。
-
在
Application
的建構函式中,迴圈呼叫所有plugin
的init
函式,並將構造引數
傳遞下去(https://pixijs.download/dev/docs/packages_app_src_Application.ts.html#line95) -
在
TickerPlugin
中執行init
函式(預設autoStart
引數為true),構建定時器Ticker
。(https://pixijs.download/dev/docs/packages_ticker_src_TickerPlugin.ts.html#line101)
if (options.autoStart)
{
this._ticker.start();
}
- 在
Ticker
中初始化_tick
方法,呼叫requestAnimationFrame
(MDN),實現持續渲染。(https://pixijs.download/dev/docs/packages_ticker_src_Ticker.ts.html#line171)
this._tick = (time: number): void =>
{
this._requestId = null;
if (this.started)
{
// Invoke listeners now
this.update(time);
if (this.started && this._requestId === null && this._head.next)
{
this._requestId = requestAnimationFrame(this._tick);
}
}
};
綜上所述,要實現只渲染一次的目標,只要不去啟動_ticker
,再在需要渲染的時候執行render
即可。
- 關閉app的自動啟動
new PIXI.Application (options)
options.autoStart
: Automatically starts the rendering after the construction
(在構造結束後就自動開始渲染)
ps:該屬性的設定只能在構造時傳入,後續修改無效
- 在需要的時候主動呼叫渲染
app.render();
修改後程式碼:
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
<script type="text/javascript">
let Application = PIXI.Application,
loader = PIXI.loader,
resources = PIXI.loader.resources,
Sprite = PIXI.Sprite;
//Create a Pixi Application
let app = new Application({
width: 1000,
height: 800,
autoStart: false
});
document.body.appendChild(app.view);
loader.add("img/wall5.jpg").load(setup);
function setup() {
let img = new Sprite(resources["img/wall5.jpg"].texture);
app.stage.addChild(img);
app.render();
}
</script>
現在再觀察GPU可以發現只有一個小小的起伏後就歸0了。為了效果明顯一點,我先執行一些耗效能的操作後再繪製圖片。可以看到GPU利用率在一個高峰後就迅速回落了。
總結
請注意不同版本pixi.js
API之間的區別,以官方API文件為主。