# Source: https://pixijs.com/8.x/guides/migrations/v8.md

# v8 Migration Guide

Welcome to the PixiJS v8 Migration Guide! This document is designed to help you smoothly transition your projects from PixiJS v7 to the latest and greatest PixiJS v8. Please follow these steps to ensure a successful migration.

## Table of Contents

1. [Introduction](#introduction)
2. [Breaking Changes](#breaking-changes)
3. [Deprecated Features](#deprecated-features)
4. [Resources](#resources)

## 1. Introduction {#introduction}

PixiJS v8 introduces several exciting changes and improvements that dramatically enhance the performance of the renderer. While we've made efforts to keep the migration process as smooth as possible, some breaking changes are inevitable. This guide will walk you through the necessary steps to migrate your PixiJS v7 project to PixiJS v8.

## 2. Breaking Changes {#breaking-changes}

Before diving into the migration process, let's review the breaking changes introduced in PixiJS v8. Make sure to pay close attention to these changes as they may impact your existing codebase.

### Should I Upgrade?

Generally, the answer is yes! But currently, there may be reasons that suggest it's best not to upgrade just yet. Ask yourself the following question:

- **Does your project leverage existing Pixi libraries that have not yet been migrated to v8?**
  We are working hard to migrate our key libraries to v8 but did not want this to be a blocker for those who are using pure Pixi. This means some libraries will not have a v8 counterpart just yet. It's best to hold off on migration if this is the case for you.

**Migrated**

- Filters
- Sound
- Gif
- Storybook
- UI
- Open Games

**Migrating Right Now:**

- React
- Spine (esoteric version)

**To Be Migrated:**

- Pixi layers (rather than migrating this, we will likely incorporate it directly into PixiJS v8 as a feature)

### **New Package Structure**

Since version 5, PixiJS has utilized individual sub-packages to organize its codebase into smaller units. However, this approach led to issues, such as conflicting installations of different PixiJS versions, causing complications with internal caches.

In v8, PixiJS has reverted to a single-package structure. While you can still import specific parts of PixiJS, you only need to install the main package.

**Old:**

```ts
import { Application } from '@pixi/app';
import { Sprite } from '@pixi/sprite';
```

**New:**

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

#### Custom Builds

PixiJS uses an "extensions" system to add renderer functionality. By default, PixiJS includes many extensions for a comprehensive out-of-the-box experience. However, for full control over features and bundle size, you can manually import specific PixiJS components.

```ts
// imported by default
import 'pixi.js/accessibility';
import 'pixi.js/app';
import 'pixi.js/events';
import 'pixi.js/filters';
import 'pixi.js/sprite-tiling';
import 'pixi.js/text';
import 'pixi.js/text-bitmap';
import 'pixi.js/text-html';
import 'pixi.js/graphics';
import 'pixi.js/mesh';
import 'pixi.js/sprite-nine-slice';

// not added by default, everyone needs to import these manually
import 'pixi.js/advanced-blend-modes';
import 'pixi.js/unsafe-eval';
import 'pixi.js/prepare';
import 'pixi.js/math-extras';
import 'pixi.js/dds';
import 'pixi.js/ktx';
import 'pixi.js/ktx2';
import 'pixi.js/basis';

import { Application } from 'pixi.js';

const app = new Application();

await app.init({
  manageImports: false, // disable importing the above extensions
});
```

When initializing the application, you can disable the auto-import feature, preventing PixiJS from importing any extensions automatically. You'll need to import them manually, as demonstrated above.

It should also be noted that the `pixi.js/text-bitmap`, also add `Assets` loading functionality.
Therefore if you want to load bitmap fonts **BEFORE** initialising the renderer, you will need to import this extension.

```ts
import 'pixi.js/text-bitmap';
import { Assets, Application } from 'pixi.js';

await Assets.load('my-font.fnt'); // If 'pixi.js/text-bitmap' is not imported, this will not load
await new Application().init();
```

### **Async Initialisation**

PixiJS will now need to be initialised asynchronously. With the introduction of the WebGPU renderer PixiJS will now need to be awaited before being used

**Old:**

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

const app = new Application();

// do pixi things
```

**New:**

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

const app = new Application();

(async () => {
  await app.init({
    // application options
  });

  // do pixi things
})();
```

With this change it also means that the `ApplicationOptions` object can now be passed into the `init` function instead of the constructor.

### ** Texture adjustments **

Textures structures have been modified to simplify what was becoming quite a mess behind the scenes in v7.
Textures no longer know or manage loading of resources. This needs to be done upfront by you or the assets manager. Textures expect full loaded resources only. This makes things so much easier to manage as the validation of a texture can essentially be done at construction time and left at that!
BaseTexture no longer exists. In stead we now have a variety of TextureSources available. A texture source combines the settings of a texture with how to upload and use that texture. In v8 there are the following texture sources:

TextureSource - a vanilla texture that you can render too or upload however you wish. (used mainly by render textures)
ImageSource - a texture source that contains an image resource of some kind (eg ImageBitmap or html image)
CanvasSource - a canvas source that contains a canvas. Used mainly for rendering canvases or rendering to a canvas (webGPU)
VideoSource - a texture source that contains a video. Takes care of updating the texture on the GPU to ensure that they stay in sync.
BufferSource - a texture source that contains a buffer. What ever you want really! make sure your buffer type and format are compatible!
CompressedSource - a texture source that handles compressed textures. Used by the GPU compressed texture formats.

Whilst the majority of the time `Assets` will return Textures you may want to make you own! More power to ya!

To create a texture source the signature differs from baseTexture. example:

```

const image = new Image();

image.onload = function(){

  // create a texture source
  const source = new ImageSource({
    resource: image,
  });

  // create a texture
  const texture = new Texture({
    source
  });
}

image.src = 'myImage.png';

```

### **Graphics API Overhaul**

There are a few key changes to the Graphics API. In fact this is probably the most changed part of v8. We have added deprecations where possible but below is the rundown of changes:

- Instead of beginning a fill or a stroke and then building a shape, v8 asks you to build your shape and then stroke / fill it. The terminology of `Line` has been replaced with the terminology of `Stroke`

**Old:**

```ts
// red rect
const graphics = new Graphics()
  .beginFill(0xff0000)
  .drawRect(50, 50, 100, 100)
  .endFill();

// blue rect with stroke
const graphics2 = new Graphics()
  .lineStyle(2, 'white')
  .beginFill('blue')
  .circle(530, 50, 140, 100)
  .endFill();
```

**New:**

```ts
// red rect
const graphics = new Graphics().rect(50, 50, 100, 100).fill(0xff0000);

// blue rect with stroke
const graphics2 = new Graphics()
  .rect(50, 50, 100, 100)
  .fill('blue')
  .stroke({ width: 2, color: 'white' });
```

- Shape functions have been renamed. Each drawing function has been simplified into a shorter version of its name. They have the same parameters though:

| v7 API Call        | v8 API Equivalent |
| ------------------ | ----------------- |
| drawChamferRect    | chamferRect       |
| drawCircle         | circle            |
| drawEllipse        | ellipse           |
| drawFilletRect     | filletRect        |
| drawPolygon        | poly              |
| drawRect           | rect              |
| drawRegularPolygon | regularPoly       |
| drawRoundedPolygon | roundPoly         |
| drawRoundedRect    | roundRect         |
| drawRoundedShape   | roundShape        |
| drawStar           | star              |

- fills functions expect `FillStyle` options or a color, rather than a string of parameters. This also replaces `beginTextureFill`

**Old:**

```ts
const rect = new Graphics()
  .beginTextureFill({ texture: Texture.WHITE, alpha: 0.5, color: 0xff0000 })
  .drawRect(0, 0, 100, 100)
  .endFill()
  .beginFill(0xffff00, 0.5)
  .drawRect(100, 0, 100, 100)
  .endFill();
```

**New:**

```ts
const rect = new Graphics()
  .rect(0, 0, 100, 100)
  .fill({ texture: Texture.WHITE, alpha: 0.5, color: 0xff0000 })
  .rect(100, 0, 100, 100)
  .fill({ color: 0xffff00, alpha: 0.5 });
```

- stokes functions expect `StrokeStyle` options or a color, rather than a string of parameters. This also replaces `lineTextureStyle`
  **Old:**

```ts
  const rect = new Graphics()
    .lineTextureStyle({texture:Texture.WHITE, width:10, color:0xFF0000})
    .drawRect(0, 0, 100, 100)
    .endFill()
    .lineStyle(2, 0xFEEB77);
    .drawRect(100, 0, 100, 100)
    .endFill();

```

**New:**

```ts
const rect = new Graphics()
  .rect(0, 0, 100, 100)
  .stroke({ texture: Texture.WHITE, width: 10, color: 0xff0000 })
  .rect(100, 0, 100, 100)
  .stroke({ color: 0xfeeb77, width: 2 });
```

- holes now make use of a new `cut` function. As with `stroke` and `fill`, `cut` acts on the previous shape.
  **Old:**

```ts
const rectAndHole = new Graphics()
  .beginFill(0x00ff00)
  .drawRect(0, 0, 100, 100)
  .beginHole()
  .drawCircle(50, 50, 20)
  .endHole()
  .endFill();
```

**New:**

```ts
const rectAndHole = new Graphics()
  .rect(0, 0, 100, 100)
  .fill(0x00ff00)
  .circle(50, 50, 20)
  .cut();
```

- `GraphicsGeometry` has been replaced with `GraphicsContext` this allows for sharing of `Graphics` data more efficiently.

**Old:**

```ts
const rect = new Graphics()
  .beginFill(0xff0000)
  .drawRect(50, 50, 100, 100)
  .endFill();

const geometry = rect.geometry;

const secondRect = new Graphics(geometry);
```

**New:**

```ts
const context = new GraphicsContext().rect(50, 50, 100, 100).fill(0xff0000);

const rect = new Graphics(context);
const secondRect = new Graphics(context);
```

### Shader changes

As we now need to accommodate both WebGL and WebGPU shaders, the way they are constructed has been tweaked to take this into account. The main differences you will notice (this is for shaders in general) is that Textures are no longer considered uniforms (as in they cannot be included in a uniform group). Instead we have the concept of resources. A resource can be a few things including:

- TextureSource - A source texture `myTexture.source`
- TextureStyle - A texture style `myTexture.style`
- UniformGroup - A collection of number based uniforms `myUniforms = new UniformGroup({})`
- BufferResource - A buffer that is treated as a uniform group (advanced)

creating a webgl only shader now looks like this:

**old**

```ts
const shader = PIXI.Shader.from(vertex, fragment, uniforms);
```

**new**

just WebGL

```ts
const shader = Shader.from({
  gl: { vertex, fragment },
  resources, // resource used from above including uniform groups
});
```

WebGL and WebGPU

```ts
const shader = Shader.from({
  gl: { vertex, fragment },
  gpu: {
    vertex: {
      entryPoint: 'mainVert',
      source,
    },
    fragment: {
      entryPoint: 'mainFrag',
      source,
    },
  },
  resources, // resource used from above including uniform groups
});
```

Uniforms are also constructed in a slightly different way. When creating them, you now provide the type of variable you want it to be.

**old**

```ts
const uniformGroup = new UniformGroup({
  uTime: 1,
});

uniformGroup.uniforms.uTime = 100;
```

**new**

```ts
const uniformGroup = new UniformGroup({
  uTime:{value:1, type:'f32',
});

uniformGroup.uniforms.uTime = 100; // still accessed the same!
```

The best way to play and fully and get to know this new setup please check out the Mesh and Shader examples:

**old**: [v7 example](https://pixijs.com/7.x/examples/mesh-and-shaders/triangle-color)
**new**: [v8 example](https://pixijs.com/8.x/examples/mesh-and-shaders/triangle-color)

### Filters

Filters work almost exactly the same, unless you are constructing a custom one. If this is the case, the shader changes mentioned above need to taken into account.

**old**

```ts
const filter = new Filter(vertex, fragment, {
  uTime: 0.0,
});
```

**new**

```ts
const filter = new Filter({
  glProgram: GlProgram.from({
    fragment,
    vertex,
  }),
  resources: {
    timeUniforms: {
      uTime: { value: 0.0, type: 'f32' },
    },
  },
});
```

**old**: [v7 example](https://pixijs.com/7.x/examples/filters-advanced/custom)
**new**: [v8 example](https://pixijs.com/8.x/examples/filters-advanced/custom)

If you're using the [community filters](https://github.com/pixijs/filters), note that the `@pixi/filter-*` packages are no-longer maintained for v8, however, you can import directly from the `pixi-filters` package as sub-modules.

**\*old**

```ts
import { AdjustmentFilter } from '@pixi/filter-adjustment';
```

**\*new**

```ts
import { AdjustmentFilter } from 'pixi-filters/adjustment';
```

---

### ParticleContainer

`ParticleContainer` has been reworked in v8 to allow for far more particles than before. There are a few key changes you should be aware of:

A `ParticleContainer` no longer accepts sprites as its children. Instead, it requires a `Particle` class (or an object that implements the `IParticle` interface), which follows this interface:

```
export interface IParticle
{
    x: number;
    y: number;
    scaleX: number;
    scaleY: number;
    anchorX: number;
    anchorY: number;
    rotation: number;
    color: number;
    texture: Texture;
}
```

The reason for this change is that sprites come with many extra properties and events that are generally unnecessary when dealing with large numbers of particles. This approach explicitly removes any ambiguity we had in v7, such as "Why doesn't my sprite work with filters?" or "Why can't I nest children in my sprites?" It’s a bit more predictable. Additionally, due to the lightweight nature of particles, this means we can render far more of them!

So, no functionality is lost—just an API tweak with a massive performance boost!

Particles are also not stored in the `children` array of the `ParticleContainer`, as particles are not technically part of the scene graph (for performance reasons). Instead, they are stored in a flat list called `particleChildren`, which is part of the `ParticleContainer` class. You can modify this array directly for extra speed, or you can use the `addParticle` and `removeParticle` methods to manage your particles.

Another optimization is that `ParticleContainer` does not calculate its own bounds, as doing so would negate the performance gains we've created! Instead, it's up to you to provide a `boundsArea` when initializing the `ParticleContainer`.

---

**OLD**

```ts
const container = new ParticleContainer();

for (let i = 0; i  {
  sprite.onViewUpdate;
});
```

The act of adding and removing the event when a sprite's texture was changed led to an unacceptable performance drop, especially when swapping many textures (imagine shooting games with lots of keyframe textures swapping). This is why we now leave that responsibility to the user.

- New Container culling approach

  With this version of PixiJS we have changed how the `cullable` property works on containers. Previously culling was done for you automatically during the render loop. However, we have moved this logic out and provided users the ability to control when culling happens themselves.

  With this change we have added a couple of new properties:
  - `cullable` - Whether or not the container can be culled
  - `cullArea` - A cull area that will be used instead of the bounds of the container
  - `cullableChildren` - Whether or not the containers children can be culled. This can help optimise large scenes

  **New:**

  ```ts
  const container = new Container();
  const view = new Rectangle(0, 0, 800, 600);

  container.cullable = true;
  container.cullArea = new Rectangle(0, 0, 400, 400);
  container.cullableChildren = false;

  Culler.shared.cull(myContainer, view);
  renderer.render(myContainer);
  ```

  There is also a `CullerPlugin` that can be used to automatically call `Culler.shared.cull` every frame if you want to simulate the old behaviour.

  ```ts
  import { extensions, CullerPlugin } from 'pixi.js';
  extensions.add(CullerPlugin);
  ```

- Renamed several mesh classes
  - renamed `SimpleMesh` -> `MeshSimple`
  - renamed `SimplePlane` -> `MeshPlane`
  - renamed `SimpleRope` -> `MeshRope`

- Deprecations for `Assets` removed

  **Old:**

  ```ts
  import { Assets } from 'pixi.js';

  Assets.add('bunny', 'bunny.png');
  ```

  **New:**

  ```ts
  import { Assets } from 'pixi.js';

  Assets.add({ alias: 'bunny', src: 'bunny.png' });
  ```

- `settings` object has been removed

  **Old:**

  ```ts
  import { settings, BrowserAdapter } from 'pixi.js';

  settings.RESOLUTION = 1;
  settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
  settings.ADAPTER = BrowserAdapter;
  ```

  **New:**

  ```ts
  import { AbstractRenderer, DOMAdapter, BrowserAdapter } from 'pixi.js';

  // Can also be passed into the renderer directly e.g `autoDetectRenderer({resolution: 1})`
  AbstractRenderer.defaultOptions.resolution = 1;

  // Can also be passed into the renderer directly e.g `autoDetectRenderer({failIfMajorPerformanceCaveat: false})`
  AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat = false;

  // See below for more information about changes to the adapter
  DOMAdapter.set(BrowserAdapter);
  ```

- Adapter and Web Worker Changes
  - `settings.ADAPTER` has been removed and replaced with `DOMAdapter`
    - `DOMAdapter` is a static class that can be used to set the adapter for the entire application
    - PixiJS has two adapters built in `BrowserAdapter` and `WebWorkerAdapter`
      - `BrowserAdapter` is the default adapter and is used when running in the browser
      - `WebWorkerAdapter` is used when running in a web worker

    **Old:**

    ```ts
    import { settings, WebWorkerAdapter } from 'pixi.js';

    settings.ADAPTER = WebWorkerAdapter;
    settings.ADAPTER.createCanvas();
    ```

    **New:**

    ```ts
    import { DOMAdapter, WebWorkerAdapter } from 'pixi.js';

    DOMAdapter.set(WebWorkerAdapter);
    DOMAdapter.get().createCanvas();
    ```

- Application type now accepts Renderer instead of view by @Zyie in https://github.com/pixijs/pixijs/pull/9740

  This is to allow `app.renderer` to be typed correctly

  **Old:**

  ```ts
  const app = new Application();
  ```

  **New:**

  ```ts
  // WebGL or WebGPU renderer
  const app = new Application>();
  // WebGL specific renderer
  const app = new Application>();
  // WebGPU specific renderer
  const app = new Application>();
  ```

* `Texture.from` no longer will load a texture from a URL.

  When using `Texture.from` you will need to pass in a source such as `CanvasSource`/`ImageSource`/`VideoSource` or a resource such as `HTMLImageElement`/`HTMLCanvasElement`/`HTMLVideoElement` or a string that has been loaded through `Assets.load`

  **Old:**

  ```ts
  import { Texture } from 'pixi.js';

  const texture = Texture.from('https://i.imgur.com/IaUrttj.png');
  ```

  **New:**

  ```ts
  import { Assets, Texture } from 'pixi.js';

  await Assets.load('https://i.imgur.com/IaUrttj.png');
  const texture = Texture.from('https://i.imgur.com/IaUrttj.png');
  ```

- The `Ticker`'s callback will now pass the `Ticker` instance instead of the delta time.
  This is to allow for more control over what unit of time is used.

  **Old:**

  ```ts
  Ticker.shared.add((dt) => {
    bunny.rotation += dt;
  });
  ```

  **New:**

  ```ts
  Ticker.shared.add((ticker) => {
    bunny.rotation += ticker.deltaTime;
  });
  ```

- Text parsers have been renamed
  - `TextFormat` -> `bitmapFontTextParser`
  - `XMLStringFormat` -> `bitmapFontXMLStringParser`
  - `XMLFormat` -> `bitmapFontXMLParser`

- The default `eventMode` is now `passive` instead of `auto`

- `utils` has been removed. All the functions are available as direct imports.

  **Old:**

  ```ts
  import { utils } from 'pixi.js';

  utils.isMobile.any();
  ```

  **New:**

  ```ts
  import { isMobile } from 'pixi.js';

  isMobile.any();
  ```

- `container.getBounds()` now returns a [`Bounds`](https://pixijs.download/release/docs/rendering.Bounds.html) object instead of a [`Rectangle`](https://pixijs.download/release/docs/maths.Rectangle.html) object. You can access the rectangle by using `container.getBounds().rectangle` instead.

  **Old:**

  ```ts
  const bounds = container.getBounds();
  ```

  **New:**

  ```ts
  const bounds = container.getBounds().rectangle;
  ```

- `container.cacheAsBitmap` has been replaced with `container.cacheAsTexture()`. They do the same things, except we changed the name `cacheAsTexture` as the Bitmap terminology is not really relevant to PixiJS.

  **Old:**

  ```ts
  container.cacheAsBitmap = true;
  ```

  **New:**

  ```ts
  container.cacheAsTexture(true);
  ```

## 3. Deprecated Features {#deprecated-features}

Certain features from PixiJS v7 have been deprecated in v8. While they will still work, it's recommended to update your code to use the new alternatives. Refer to the deprecated features section for details on what to replace them with.

- Leaf nodes no longer allow children

  Only `Containers` can have children. This means that `Sprite`, `Mesh`, `Graphics` etc can no longer have children.

  To replicate the old behaviour you can create a `Container` and add the leaf nodes to it.

  **Old:**

  ```ts
  const sprite = new Sprite();
  const spriteChild = new Sprite();
  sprite.addChild(spriteChild);
  ```

  **New:**

  ```ts
  const container = new Container();
  const sprite = new Sprite();
  const spriteChild = new Sprite();

  container.addChild(sprite);
  container.addChild(spriteChild);
  ```

- `Application.view` replaced with `Application.canvas`

  **Old:**

  ```ts
  const app = new Application({ view: document.createElement('canvas') });
  document.body.appendChild(app.view);
  ```

  **New:**

  ```ts
  const app = new Application();
  await app.init({ view: document.createElement('canvas') });
  document.body.appendChild(app.canvas);
  ```

- `NineSlicePlane` renamed to `NineSliceSprite`

- `SCALE_MODES` replaced with `ScaleMode` strings
  - `SCALE_MODES.NEAREST` -> `'nearest'`,
  - `SCALE_MODES.LINEAR` -> `'linear'`,

- `WRAP_MODES` replaced with `WrapMode` strings
  - `WRAP_MODES.CLAMP` -> `'clamp-to-edge'`,
  - `WRAP_MODES.REPEAT` -> `'repeat'`,
  - `WRAP_MODES.MIRRORED_REPEAT` -> `'mirror-repeat'`,

- `DRAW_MODES` replaced with `Topology` strings
  - `DRAW_MODES.POINTS` -> `'point-list'`,
  - `DRAW_MODES.LINES` -> `'line-list'`,
  - `DRAW_MODES.LINE_STRIP` -> `'line-strip'`,
  - `DRAW_MODES.TRIANGLES` -> `'triangle-list'`,
  - `DRAW_MODES.TRIANGLE_STRIP` -> `'triangle-strip'`,

- Constructors have largely been changed to accept objects instead of multiple arguments

  **Old:**

  ```ts
  const blurFilter = new BlurFilter(8, 4, 1, 5);
  const displacementFilter = new DisplacementFilter(sprite, 5);
  const meshGeometry = new MeshGeometry(vertices, uvs, index);
  const mesh = new Mesh(geometry, shader, state, drawMode);
  const plane = new PlaneGeometry(width, height, segWidth, segHeight);
  const nineSlicePlane = new NineSlicePlane(
    texture,
    leftWidth,
    topHeight,
    rightWidth,
    bottomHeight,
  );
  const tileSprite = new TileSprite(texture, width, height);
  const text = new Text('Hello World', style);
  const bitmapText = new BitmapText('Hello World', style);
  const htmlText = new HTMLText('Hello World', style);
  ```

  **New:**

  ```ts
  const blurFilter = new BlurFilter({
      blur: 8,
      quality: 4,
      resolution: 1,
      kernelSize: 5,
  });
  const displacementFilter = new DisplacementFilter({
      sprite,
      scale: 5,
  });
  const meshGeometry = new MeshGeometry({
      positions: vertices,
      uvs,
      indices: index,
      topology: 'triangle-list';
      shrinkBuffersToFit: boolean;
  });
  const mesh = new Mesh({
      geometry
      shader
      texture
  });
  const plane = new PlaneGeometry({
      width,
      height,
      verticesX: segWidth,
      verticesY: segHeight,
  });
  const nineSliceSprite = new NineSliceSprite({
      texture,
      leftWidth,
      topHeight,
      rightWidth,
      bottomHeight,
  });
  const tileSprite = new TileSprite({
      texture,
      width,
      height,
  });
  const text = new Text({
      text: 'Hello World',
      style,
  });
  const bitmapText = new BitmapText({
      text:'Hello World',
      style,
  });
  const htmlText = new HTMLText({
      text:'Hello World',
      style,
  });
  ```

- `container.name` is now `container.label`

## 4. Resources {#resources}

- [PixiJS v8 Release Notes](https://github.com/pixijs/pixijs/releases?q=v8.0.0&expanded=true)
- [PixiJS Discord](https://discord.gg/CPTjeb28nH)
- [PixiJS Issues](https://github.com/pixijs/pixijs/issues)