---
title: "PixiJSとは？WebGL/WebGPUで動く2D描画エンジンの使い方をv8.22対応で解説"
url: "https://www.issoh.co.jp/tech/details/9180/"
published: 2025-10-06
updated: 2026-10-18
categories: ["フレームワーク"]
publisher: "株式会社一創"
---

# PixiJSとは？WebGL/WebGPUで動く2D描画エンジンの使い方をv8.22対応で解説

PixiJSは、ブラウザのGPUを使って2Dグラフィックスを高速に描画するオープンソースのJavaScriptライブラリです。WebGLやWebGPUのコードを直接書かずに、スプライト・図形・テキスト・フィルターを組み合わせた2D表現を作れます。ライセンスはMITで、商用でも無償です。この記事では、2026年10月1日（UTC）公開の最新版 pixi.js 8.22.0 を前提に、導入と初期化、図形と画像の表示、キー入力と当たり判定を使った小さなゲーム、ドラッグ、大量描画の最適化、v7以前のコードを動かすときの注意点までを、実行して動作を確かめたコードで説明します。

## まとめ：PixiJSの要点

- **PixiJSはWebGL/WebGPUで描く2D専用の描画エンジン**。3Dのシーンやカメラは持たないので、3D主体ならThree.jsを選ぶ。
- **最新は8.22.0（2026年10月1日・UTC）**。v8は2024年3月5日に正式公開され、以後は8.x系のマイナー更新が続いている。
- **既定のレンダラーはWebGL**。WebGPUを優先させるには `preference: 'webgpu'` を指定する（未指定のときはWebGLが使えない場合の次の候補）。公式ドキュメントではWebGPUは実験的扱いで、v8.16.0からはCanvas 2Dのレンダラーも選べる。
- 初期化は `await app.init()` で待つ。図形は `circle().fill()` のように「形を描いてから塗る」書き方になった。
- ゲームの基本は「表示物を作る→`app.stage` に追加→`app.ticker` で毎フレーム更新」。キー入力・当たり判定・スコア表示もこの流れの中に書く。
- v7の `beginFill()` などは8.22.0でも警告付きで動くが、`ParticleContainer.addChild()` のように例外になるものもある。

以下、位置づけ→v8の変更点→導入→描画→ゲームの基本処理→イベント→最適化→連携→移行の注意点の順に説明します。

## PixiJSでできること・向かないこと

PixiJSは、画像を「テクスチャを貼った四角形」、図形を「三角形の集合」としてGPUへ渡し、同じテクスチャを使うスプライトを、描画順やブレンドモードなどの条件が揃う範囲で1回の描画命令にまとめます（バッチ描画）。Canvas 2Dで1つずつ描くより、オブジェクト数が増えたときに差が出ます。

向いているのは、大量のスプライトを動かす2Dゲーム、キャンペーンサイトのインタラクティブな演出、Canvasに描く可視化やUIです。公式の[v8リリース告知](https://pixijs.com/blog/pixi-v8-launches)には、10万個のスプライトがすべて動く条件で、1フレームのCPU時間がv7の約50msからv8では約15ms、GPU時間が約9msから約2msに減ったベンチマークが載っています。

向かないのは、HTMLのフォームや文章が主体の画面です。テキスト入力やスクリーンリーダー対応はDOMの方が素直で、PixiJSの `accessibilityOptions` は補助的な仕組みと考えた方が安全です。物理演算・シーン管理・入力管理まで含むゲームエンジンが欲しい場合は、PixiJSの上に自分で組むより[Phaser.jsとは？使い方・入門をPhaser 4対応で解説](/tech/details/3050/)で扱うPhaserのようなフレームワークを選ぶ方が早く完成します。

### 3D表現を扱いたい場合の選択肢

PixiJS本体には、3Dモデルの読み込み・カメラ・ライトを備えた3Dシーンの機能はありません。v8.22.0で追加された3Dテクスチャは、シェーダーを自分で書く人向けの低レベル機能です。コミュニティ製の3D拡張 [Pixi3D](https://github.com/jnsmalm/pixi3d) はREADMEで対応をPixiJS v5・v6・v7と書いており、npmの最新版は2023年12月の2.5.0のまま、v8向けの版は出ていません。v8で3Dを足すなら、3D部分を[Three.jsとは？r185の導入手順とglTF表示・バンドルサイズ実測まで解説](/tech/details/3051/)で扱うThree.jsに任せ、2DのUIや演出をPixiJSで重ねる構成が現実的です。

## PixiJS v8の主な変更点とv7との違い

v8は内部を作り直したメジャー版で、v7以前の記事のコードは動かない箇所や警告が出る箇所があります。よく出会う書き換えを先に表にまとめます。「8.22.0での扱い」は実際に呼び出して確かめた結果です。

| 用途       | v7以前                         | v8                          | 8.22.0で旧書式を使うと                  |
| -------- | ---------------------------- | --------------------------- | ------------------------------- |
| 初期化      | `new Application({...})`     | `await app.init({...})`     | init前の `app.canvas` は TypeError |
| canvas取得 | `app.view`                   | `app.canvas`                | 警告付きで同じcanvasを返す                |
| 図形の塗り    | `beginFill()`→`drawCircle()` | `circle().fill()`           | 警告付きで描ける                        |
| 操作可能にする  | `interactive = true`         | `eventMode = 'static'`      | 警告なしで static になる                |
| 名前を付ける   | `name`                       | `label`                     | 警告付きで label に入る                 |
| 静止画キャッシュ | `cacheAsBitmap`              | `cacheAsTexture()`          | 警告付きで動く                         |
| Textの生成  | `new Text('文字', style)`      | `new Text({ text, style })` | 警告付きで動く                         |
| 画像の読み込み  | v6以前：`Loader`                | `Assets.load()`（v7から）       | Loaderは存在しない                    |
| パーティクル追加 | `addChild()`                 | `addParticle()`             | 例外が出る                           |

警告は「PixiJS Deprecation Warning」という見出しでコンソールに1種類につき1回だけ出ます。動いてしまうぶん見落としやすいので、v7の記事からコードを持ってきたらコンソールを確認してください。書き換えの全体は公式の[v8 Migration Guide](https://pixijs.com/8.x/guides/migrations/v8)にあります。

### レンダラーの選択とWebGL・WebGPUの優先順

「v8はWebGPU対応環境で自動的にWebGPUを使う」と説明されることがありますが、8.22.0の実装は違います。`autoDetectRenderer` の優先順は `["webgl", "webgpu", "canvas"]` で、`preference` を指定しなければWebGLが選ばれ、WebGLが使えないときに初めてWebGPUが試されます。[8.22.0のAPIリファレンス](https://pixijs.download/v8.22.0/docs/rendering.autoDetectRenderer.html)も、WebGPUが安定して普及した時点でWebGLより優先する予定だと書いています。WebGPUが使えるようにしたChrome 155で `preference` なしで初期化しても、`app.renderer.name` は `webgl` でした。公式の[Renderersガイド](https://pixijs.com/8.x/guides/components/renderers)もWebGLRendererを「Recommended」、WebGPURendererを「Experimental」とし、本番ではWebGLを勧めています。

```
import { Application } from 'pixi.js';

const app = new Application();
await app.init({ preference: 'webgpu' }); // 使えなければ WebGL→Canvas の順に試す
console.log(app.renderer.name);          // 'webgpu' / 'webgl' / 'canvas'

// 8.18.0以降は候補と順番を配列で渡せる（この例ではCanvasには切り替わらない）
// await app.init({ preference: ['webgpu', 'webgl'] });
```

文字列で指定すると、そのレンダラーが使えないときは残りを既定の順で試します。8.18.0からは配列で候補と順番を指定でき、配列に含めなかったレンダラーには切り替わりません。[v8.16.0](https://pixijs.com/blog/8.16.0)で実験的機能として追加されたCanvasレンダラー（`preference: 'canvas'`、`renderer.name` は `canvas`）は、WebGLもWebGPUも使えない環境の最後の受け皿です。WebGPUを選ぶのは、WGSLシェーダーやコンピュート寄りの機能を使う、と決めている場合に限るのが無難です。ブラウザ側では、Chromeが[113](https://developer.chrome.com/blog/webgpu-release)でWindows・macOS・ChromeOS向けにWebGPUを既定で有効にし、Safariは[26.0](https://webkit.org/blog/17333/webkit-features-in-safari-26-0/)で出荷しました。FirefoxはWindowsが141、Apple Silicon搭載Macは147で全macOS版に広がりましたが、LinuxとIntel Macで既定で有効なのはNightlyです。Firefoxの経緯は[Firefox 147の新機能と変更点](/tech/details/10662/)にまとめています。

### 初期化の非同期化（await app.init()）

WebGPUの初期化が非同期であるため、v8では `Application` を作ったあと `await app.init()` を待ってから使います。サイズや背景色のオプションも `init()` に渡します。init前の `app.canvas` はTypeErrorになります。一方 `app.stage` はコンストラクタの時点で作られており、init前に追加した表示物もinit後にそのまま描かれます（init前に円を追加してから初期化し、中心が赤で描画されることを確認）。何も表示されないときは、`init()` を呼んでいないか、canvasをページに置いていないかを疑います。トップレベルの `await` が使えない環境では、非同期関数で包むか `app.init().then(...)` で続きを書きます。

### Graphics APIの刷新

v7は「塗り色を決めてから図形を描く」流れでしたが、v8は「形を描いてから塗る・線を引く」流れです。メソッドチェーンでつなげられます。

```
const g = new Graphics();
g.circle(50, 60, 30).fill(0xff0000);                                       // 赤い円
g.rect(120, 30, 60, 60).fill(0x00aaff).stroke({ width: 4, color: 0x003366 }); // 枠付きの四角
```

`drawRect()` は `rect()`、`drawCircle()` は `circle()`、線は `lineStyle()` ではなく `stroke()`（線の書式だけ先に決めるなら `setStrokeStyle()`）、穴あけは `cut()` です。8.22.0のヘッドレスChromeでこの2つの図形を描き、円の中心が赤（255,0,0）、四角の中心が水色（0,170,255）、枠線が紺（0,51,102）で描画されることをピクセル単位で確認しました。

### 8.20〜8.22で変わった挙動

8.x系のマイナー更新でも、結果が変わる修正が入っています（日付はGitHubのリリース日・UTC）。当たり判定やコンテキストメニューを扱うコードは、更新前後で動きを見直してください。

- **8.20.0（2026年8月20日）**：`Polygon.strokeContains` の判定幅が描画された線と一致するよう修正。`Rectangle.containsRect` は同じ大きさの矩形や右端・下端に接する矩形で true を返すようになった。
- **8.21.0（2026年9月17日）**：TypeScript 6・7に対応。`Matrix.decompose()` が反転した行列を負の `scale.x` として返すようになった。
- **8.22.0（2026年10月1日）**：右クリックの `contextmenu` イベントが表示物に届くようになった。8.14.0で壊れていた「Tabキーでアクセシビリティ層が有効になる」既定動作が直った。

8.22.0の変更は[v8.22.0のリリースノート](https://github.com/pixijs/pixijs/releases/tag/v8.22.0)にコード付きで載っています。8.20.0と8.21.0の変更はそれぞれの版のリリースノートで確認できます。

## PixiJSの導入と初期化

導入はCDNの読み込み、npmでの追加、公式の雛形作成コマンドの3通りです。試すだけならCDN、実プロジェクトならnpmか雛形を使います。以下のコード例は、npmで導入したバンドラ環境（Viteなど）のモジュールとして書いています。CDNの通常のscriptタグで試すなら、`import` 文を `const { Application } = PIXI;` のような分割代入に置き換え、`await` を含む処理を非同期関数で包んでください。

### CDNによるPixiJSの読み込み

HTMLに次の1行を足すと、グローバル変数 `PIXI` から全クラスを使えます。`@8.22.0` のように版を固定しておくと、将来の更新で挙動が変わる事故を防げます。ES Modulesで使う場合は、`<script type="module">` の中で末尾が `pixi.min.mjs` のURLから `import` します。この方式ではグローバル変数 `PIXI` は作られません。

```
<script src="https://cdn.jsdelivr.net/npm/pixi.js@8.22.0/dist/pixi.min.js"></script>
```

### npmによるPixiJSの追加と雛形の作成

バンドラを使うプロジェクトでは `pixi.js` を追加します。v8はパッケージが1つに統合されたので、v7の `@pixi/sprite` のような分割パッケージは使いません。新規に始めるなら、公式の[Quick Start](https://pixijs.com/8.x/guides/getting-started/quick-start)にある `npm create pixi.js@latest` で、Viteなどのテンプレートを選んで雛形を作れます。

```
npm install pixi.js@8.22.0

# 雛形から始める場合（テンプレートを対話で選ぶ）
npm create pixi.js@latest
```

### Applicationの初期化とcanvasの配置

描画領域を管理する `Application` を作り、`init()` を待ってからcanvasをページに置きます。`resizeTo: window` を渡すと、ウィンドウの大きさに合わせてcanvasが伸び縮みします。

```
import { Application } from 'pixi.js';

const app = new Application();

// v8では init が非同期。サイズや背景色はここで渡す
await app.init({
  resizeTo: window,
  background: 0xffffff,
  antialias: true,
});

// 生成された canvas を DOM に配置（v7の app.view は非推奨）
document.body.appendChild(app.canvas);
```

## 図形とスプライトの描画・移動・回転

PixiJSの基本は「表示物を作る→`app.stage` に追加する→`app.ticker` で毎フレーム更新する」の3段階です。次の例は、赤い円を左右にバウンドさせ、画像のスプライトを中央で回転させます。

```
import { Application, Assets, Graphics, Sprite } from 'pixi.js';

const app = new Application();
await app.init({ width: 640, height: 360, background: 0xffffff });
document.body.appendChild(app.canvas);

// 1. 図形を作って塗る（v8のGraphics API）
const circle = new Graphics().circle(0, 0, 50).fill(0xff0000);
circle.position.set(60, 100);
app.stage.addChild(circle);

// 2. 画像を読み込んでスプライトにする（v8は Assets に一本化）
const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
const bunny = new Sprite(texture);
bunny.anchor.set(0.5);
bunny.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(bunny);

// 3. 毎フレーム更新する（端で反転するバウンド＋回転）
let vx = 3;
app.ticker.add((ticker) => {
  circle.x += vx * ticker.deltaTime;
  // 端を越えたら位置を戻してから向きを変える（戻さないと端に引っかかる）
  if (circle.x + 50 >= app.screen.width) {
    circle.x = app.screen.width - 50;
    vx = -Math.abs(vx);
  } else if (circle.x - 50 <= 0) {
    circle.x = 50;
    vx = Math.abs(vx);
  }
  bunny.rotation += 0.02 * ticker.deltaTime;
});
```

`Assets.load()` は読み込みが終わるとTextureを返します。画像の読み込みはv7で `Loader` から `Assets` へ切り替わっており、v8でもAssetsを使います。`ticker.deltaTime` は60fpsのときに約1.0になる係数で、速度に掛けておくとリフレッシュレートが120Hzの端末でも動く速さが変わりません。`anchor.set(0.5)` は回転と配置の基準点を画像の中心にする指定です。

## ゲームの基本処理：キー入力・当たり判定・スコア表示

ここからは、矢印キーで動かす四角がコインに触れるとスコアが増える、最小のゲームを作ります。PixiJSには入力管理や物理演算の仕組みが無いので、キー入力はDOMのイベント、当たり判定は表示物の矩形から自分で書きます。

```
import { Application, Graphics, Text } from 'pixi.js';

const app = new Application();
await app.init({ width: 400, height: 300, background: 0x1d1f2b });
document.body.appendChild(app.canvas);

const player = new Graphics().rect(0, 0, 40, 40).fill(0x4fc3f7);
player.position.set(20, 130);
const coin = new Graphics().circle(0, 0, 12).fill(0xffd54f);
coin.position.set(300, 150);
const scoreText = new Text({ text: 'Score: 0', style: { fill: 0xffffff, fontSize: 20 } });
app.stage.addChild(player, coin, scoreText);

// 押されているキーを保持する（keydownの連射間隔に左右されない）
const keys = new Set();
const ARROWS = ['ArrowRight', 'ArrowLeft', 'ArrowDown', 'ArrowUp'];
window.addEventListener('keydown', (e) => {
  if (!ARROWS.includes(e.key)) return;
  e.preventDefault(); // 矢印キーでページがスクロールしないようにする
  keys.add(e.key);
});
window.addEventListener('keyup', (e) => keys.delete(e.key));
window.addEventListener('blur', () => keys.clear()); // 押したまま別ウィンドウへ移った場合

// 2つの表示物の外接矩形が重なっているか（AABB）
function hitTest(a, b) {
  const p = a.getBounds();
  const q = b.getBounds();
  return p.x < q.x + q.width && p.x + p.width > q.x
      && p.y < q.y + q.height && p.y + p.height > q.y;
}

let score = 0;
app.ticker.add((ticker) => {
  const speed = 4 * ticker.deltaTime; // 60fps換算で1フレーム4px
  if (keys.has('ArrowRight')) player.x += speed;
  if (keys.has('ArrowLeft')) player.x -= speed;
  if (keys.has('ArrowDown')) player.y += speed;
  if (keys.has('ArrowUp')) player.y -= speed;
  // 画面の外へ出ないように制限する
  player.x = Math.min(Math.max(player.x, 0), app.screen.width - 40);
  player.y = Math.min(Math.max(player.y, 0), app.screen.height - 40);

  if (hitTest(player, coin)) {
    score += 1;
    scoreText.text = `Score: ${score}`;
    do { // プレイヤーと重ならない位置へ置き直す
      coin.position.set(40 + Math.random() * 320, 40 + Math.random() * 220);
    } while (hitTest(player, coin));
  }
});
```

### Setによるキー入力の保持とtickerでの更新

`keydown` の中で直接座標を動かすと、キーの連射間隔（OSの設定で変わる）でしか動かず、押し始めに一瞬止まります。押されているキーを `Set` に入れておき、ticker の中で読むと毎フレーム滑らかに動きます。ヘッドレスChromeで右矢印を3秒押し続けたところ、四角は右端の制限（x=360）で止まり、途中のコインに触れてスコアが1になりました。矢印キーは既定でページをスクロールさせるので `preventDefault()` で止め、キーを押したままウィンドウを離れると `keyup` が届かないため `blur` で状態を空にしています。

### 外接矩形（AABB）による当たり判定

`getBounds()` はステージ上での外接矩形を返すので、親コンテナの位置や拡大率が違う表示物同士でも比べられます。矩形どうしなら `a.getBounds().rectangle.intersects(b.getBounds().rectangle)` でも同じ判定になります。ただし辺が接しているだけの矩形は false です（x=0〜50と x=50〜60の矩形で確認）。円形のキャラクターを矩形で判定すると角で当たりが大きく出るので、精度が要るなら中心間の距離と半径の和を比べる円判定に切り替えます。

当たり判定・状態管理・シーン遷移を自前で書く量が増えてきたら、ゲーム開発の外部委託や設計の相談先として[ゲームアプリ開発](https://www.issoh.co.jp/service/apps/game/)のような専門の支援を使う選択肢もあります。

## クリック・タッチ・ドラッグのイベント処理

PixiJSはマウス・タッチ・ペンを統一したポインタイベントを扱います。イベントを受けるかどうかは `eventMode` で決め、既定値は `'passive'`（自分は反応せず、子の反応は通す）です。v7の `interactive = true` は `'static'` に当たります。

| eventMode       | 自分のヒット判定       | 向いている対象     |
| --------------- | -------------- | ----------- |
| `'none'`        | しない（子もスキップ）    | 背景・装飾       |
| `'passive'`（既定） | しない（子は判定）      | ボタンを束ねるコンテナ |
| `'auto'`        | 親が操作可能なときだけ    | 入れ子の部品      |
| `'static'`      | する             | 静止したボタン     |
| `'dynamic'`     | する（静止中も合成イベント） | 動き回る対象      |

クリック・タップは `pointerdown` や `pointertap` を使うと、PCとスマホの両方で同じコードが動きます。8.22.0からは右クリックの `contextmenu` も受けられ、`event.preventDefault()` でブラウザのメニューを止められます。各モードの定義は公式の[Eventsガイド](https://pixijs.com/8.x/guides/components/events)にあります。

### ポインタイベントによるドラッグ処理

ドラッグ専用のイベントは無いので、`pointerdown`→`pointermove`→`pointerup` を組み合わせます。押した位置と図形の原点のずれを保存しておくと、つかんだ場所がずれません。

```
import { Application, Graphics } from 'pixi.js';

const app = new Application();
await app.init({ width: 400, height: 300, background: 0xeeeeee });
document.body.appendChild(app.canvas);

const box = new Graphics().rect(0, 0, 50, 50).fill(0xff0000);
box.position.set(100, 20);
box.eventMode = 'static';
box.cursor = 'pointer';
app.stage.addChild(box);

// 何も無い場所でも pointermove を受けられるよう、ステージ全体を当たり領域にする
app.stage.eventMode = 'static';
app.stage.hitArea = app.screen;

let dragging = false;
const offset = { x: 0, y: 0 };
box.on('pointerdown', (e) => {
  dragging = true;
  const p = e.getLocalPosition(box.parent);
  offset.x = box.x - p.x;
  offset.y = box.y - p.y;
});
app.stage.on('pointermove', (e) => {
  if (!dragging) return;
  const p = e.getLocalPosition(box.parent);
  box.position.set(p.x + offset.x, p.y + offset.y);
});
app.stage.on('pointerup', () => { dragging = false; });
app.stage.on('pointerupoutside', () => { dragging = false; });
```

要になるのは `app.stage.hitArea = app.screen` です。ステージは何も無い場所ではヒット判定されないため、これが無いとポインタが図形から外れた瞬間に `pointermove` が届かなくなります。ヘッドレスChromeでポインタを図形の外まで一気に動かすと、hitAreaありでは図形が追従し、hitAreaなしでは元の位置（100, 20）から動きませんでした。キャンバスの外で指を離した場合に備え、`pointerupoutside` も止めておきます。

## 表示順の制御と大量描画の最適化

表示物はすべて `app.stage` を根とするシーングラフで管理され、親を動かすと子も一緒に動きます。透明度（alpha）や表示状態も親から子へ掛け合わされます。

### zIndexによる表示順の制御

同じ親の子は `addChild` した順に描かれ、後から足したものほど手前に出ます。動的に入れ替えるなら親の `sortableChildren = true` を有効にし、各表示物の `zIndex` を設定します。値の大きいものが手前です（zIndex 2のAと1のBを足すと、並びはB→Aになりました）。キャラクターのy座標をzIndexに入れると、奥のキャラが背面に回る見下ろし型の表現になります。並べ替えは子の追加やzIndexの変更があったときだけ行われます。y座標を毎フレームzIndexへ写すと毎フレーム並べ替えが走るので、対象を奥行きのある層のコンテナに限ります。

### ParticleContainerによる大量の粒子の描画

同じ画像の小さな粒を数万個出すなら `ParticleContainer` を使います。v8では中身が `Sprite` ではなく軽量な `Particle` になり、追加は `addParticle()` です。`addChild()` を呼ぶと「ParticleContainer.addChild() is not available」という例外になります。

```
import { Application, Assets, Particle, ParticleContainer } from 'pixi.js';

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

const texture = await Assets.load('https://pixijs.com/assets/bunny.png');

// 既定で毎フレーム送るのは position だけ。回転させるなら rotation も true にする
const particles = new ParticleContainer({
  dynamicProperties: { position: true, rotation: true },
});
for (let i = 0; i < 10000; i++) {
  particles.addParticle(new Particle({
    texture,
    x: Math.random() * 800,
    y: Math.random() * 600,
    anchorX: 0.5,
    anchorY: 0.5,
  }));
}
app.stage.addChild(particles);

app.ticker.add((ticker) => {
  for (const p of particles.particleChildren) {
    p.rotation += 0.05 * ticker.deltaTime;
  }
});
```

既定で毎フレームGPUへ送るのは `position` だけで、`rotation`・`vertex`・`uvs`・`color` は静的扱いです。回転させるなら `dynamicProperties` で `rotation: true` にするか、変更のたびに `particles.update()` を呼びます。上の例で1万個の回転が毎フレーム更新されることを確認しました。詳細は公式の[ParticleContainerガイド](https://pixijs.com/8.x/guides/components/scene-objects/particle-container)にあります。

そのほかの工夫として、複数の画像を1枚にまとめるスプライトシート（テクスチャの切り替え回数を減らしバッチを途切れさせない）、画面外を描かないカリング（`extensions.add(CullerPlugin)` でプラグインを登録したうえで `cullable = true` を指定する。cullableの既定はfalseで、プラグインは既定で無効。手順は公式の[Culler Pluginガイド](https://pixijs.com/8.x/guides/components/application/culler-plugin)）、動かない複雑な図形を一度テクスチャにする `cacheAsTexture(true)` があります。

## 他ライブラリ・フレームワークとの連携

2026年10月時点のnpmの版と前提をまとめます。

| 用途    | パッケージ                             | 最新版    | 前提                            |
| ----- | --------------------------------- | ------ | ----------------------------- |
| React | `@pixi/react`                     | 8.0.5  | React 19以上・pixi.js 8.2.6以上9未満 |
| Spine | `@esotericsoftware/spine-pixi-v8` | 4.3.13 | pixi.js 8.16.0以上9未満           |
| UI部品  | `@pixi/ui`                        | 2.4.1  | pixi.js 8.6.2以上9未満            |
| レイアウト | `@pixi/layout`                    | 3.2.1  | pixi.js 8・yoga-layout 3       |
| サウンド  | `@pixi/sound`                     | 6.0.1  | pixi.js 8.x                   |

Reactに組み込む `@pixi/react` v8は、`extend()` で使うクラスを登録してからJSXの `<pixiSprite>` のように書く方式です。必要なクラスだけをimportして登録する形なので、バンドラのツリーシェイキングが効きやすくなります。Spineのボーンアニメーションは、Esoteric Softwareの公式ランタイム `spine-pixi-v8` で読み込みます。[公式ドキュメント](https://esotericsoftware.com/spine-pixi)によると、ランタイムとSpineエディタはmajor.minorの版を揃える必要があり、4.3.13ならSpine 4.3系で書き出したデータを使います。Spineエディタ自体の料金は[Spineの値段｜2Dアニメーションソフトの料金](/tech/details/4936/)で扱っています。

After Effectsから書き出したLottieはPixiJS単体では読めません。`lottie-web` に非表示のcanvasへ描かせ、そのcanvasを `Texture.from(canvas)` でテクスチャにし、毎フレーム `texture.source.update()` で反映する方法なら、Lottie用プラグインの対応版に縛られません（`texture.source` はv8のAPIなので、v7以前では書き換えが要ります）。座標や透明度をイージング付きで動かすならGSAPが定番で、表示物のプロパティを直接アニメーションできます。GSAPと他のライブラリの違いは[Anime.js v4の変更点と使い方｜v3からの移行手順とGSAPとの違い](/tech/details/12740/)で比べています。

## v7以前のコードを動かすときのハマりどころ

v7以前の記事のコードを写すと、次の症状が出ます。

- **何も表示されない・エラーも無い**：`app.init()` を呼ばずに表示物を追加しただけになっているか、`app.canvas` をページに追加していない。
- **「Cannot read properties of undefined (reading ‘canvas’)」**：init前に `app.canvas` を読んでいる。
- **動くがコンソールに黄色い警告が並ぶ**：`beginFill`・`drawCircle`・`lineStyle`・`app.view`・`cacheAsBitmap`・`name`・旧Text書式。警告文に置き換え先が書いてあるので、それに従って直す。
- **カーソルが指の形にならない**：v6以前の `buttonMode = true` はv7で削除され、8.22.0では警告も出さずに無視される。`cursor = 'pointer'` を指定する。

本記事のコードは、pixi.js 8.22.0 とGoogle Chrome 155のヘッドレスモード（描画はSwiftShader）で実行し、エラーが出ないことと上記の挙動を確認しています。WebGLを素で書くとどれだけの手順が要るかは[WebGLとは？仕組み・対応ブラウザの確認・三角形を描くコード](/tech/details/4884/)、WebGPUをRustから低レベルに扱う方法は[wgpuとは？RustでWebGPUを扱う仕組みと最小サンプル](/tech/details/4094/)が参考になります。

## よくある質問

### PixiJSとは何ですか？

WebGL（指定すればWebGPU）でブラウザ上に2Dグラフィックスを高速に描く、オープンソースのJavaScriptライブラリです。2026年10月時点の最新版は8.22.0です。

### PixiJSの使い方は？

`await app.init()` で初期化してcanvasをページに置き、SpriteやGraphicsを `app.stage.addChild()` で追加し、動かすものは `app.ticker.add()` で毎フレーム更新します。

### PixiJSは無料で商用利用できますか？

できます。PixiJSはMITライセンスで、商用のサイトやゲームにも無償で組み込めます。配布物に著作権表示とライセンス文を残すことが条件です。

### PixiJSで3Dは作れますか？Three.jsとの違いは？

本体は2D専用で、3D拡張のPixi3Dもv7までの対応です。立体的なシーンはThree.js、2DのUI・ゲーム・大量スプライトはPixiJSと分けます。

### PixiJSはReactで使えますか？

使えます。公式の `@pixi/react` 8.0.5で表示物をJSXとして書けます。React 19以上とpixi.js 8.2.6以上9未満が前提です。

## 関連記事

- [Three.jsとは？r185の導入手順とglTF表示・バンドルサイズ実測まで解説](/tech/details/3051/)
- [Phaser.jsとは？使い方・入門をPhaser 4対応で解説｜1ファイルで動くゲーム例・物理・3からの移行](/tech/details/3050/)
- [WebGLとは？仕組み・対応ブラウザの確認・三角形を描くコードとUnityビルドまで解説](/tech/details/4884/)
- [p5.jsとは？使い方・始め方とsetup/draw・図形の描き方を2.x対応で解説](/tech/details/7634/)
- [Anime.js v4の変更点と使い方｜v3からの移行手順とGSAPとの違い](/tech/details/12740/)

---

出典: [PixiJSとは？WebGL/WebGPUで動く2D描画エンジンの使い方をv8.22対応で解説](<https://www.issoh.co.jp/tech/details/9180/>)（株式会社一創）
