pixijs-scene-gif — Claude Code skill: what it does, how to install
Teaches coding assistants how to load and play animated GIFs in PixiJS v8 with GifSprite. Useful when embedding GIF assets directly into scene trees.
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a claude-codeWhat pixijs-scene-gif does
The skill provides patterns for PixiJS v8 GIF playback. It ensures the assistant includes the import 'pixi.js/gif' side-effect import so Assets.load recognizes .gif files and returns a GifSource instead of a plain Texture.
GifSprite extends Sprite as a leaf display object, which means you cannot nest child elements inside it. To group multiple GIF instances, place them in a Container. The constructor configures options like autoPlay, loop, animationSpeed, and event callbacks such as onComplete or onFrameChange.
GIFs decode every frame into an individual canvas texture, so high-frame animations are a good reason to audit GPU memory and switch to AnimatedSprite with a spritesheet atlas.
What it helps with
- load animated GIF files into PixiJS v8 scenes using
Assets.load - control frame playback, loop behavior, and speed on
GifSprite - handle playback events with
onComplete,onLoop, andonFrameChangecallbacks - configure fallback FPS and canvas texture resolution for GIF assets
Example prompts for the agent
- Load animation.gif using PixiJS v8 and display it centered with GifSprite
- Set up a non-looping GifSprite with an onComplete callback and custom animationSpeed
How to install pixijs-scene-gif
1Skills CLI (Vercel)
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a claude-code2Manually: put the files in place
~/.claude/skills/pixijs-scene-gif/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/pixijs-scene-gif/
1Skills CLI (Vercel)
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a codex2Manually: put the files in place
.agents/skills/pixijs-scene-gif/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a cursor2Manually: put the files in place
.cursor/skills/pixijs-scene-gif/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install pixijs/pixijs-skills pixijs-scene-gif2Manually: put the files in place
.github/skills/pixijs-scene-gif/SKILL.md1Skills CLI (Vercel)
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a gemini-cli2Platform CLI
gemini skills install https://github.com/pixijs/pixijs-skills --path skills/pixijs-scene-gifManually: put the files in place
.devin/skills/pixijs-scene-gif/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about pixijs-scene-gif
How to install pixijs-scene-gif in Claude Code?
Run npx skills add pixijs/pixijs-skills --skill pixijs-scene-gif -a claude-code in your terminal.
What does pixijs-scene-gif do?
It guides coding agents on using the pixi.js/gif package in PixiJS v8. It covers GifSource asset loading, GifSprite configuration, and playback control methods.
Why does the skill suggest AnimatedSprite for complex animations?
Each GIF frame decodes into an individual canvas texture. An AnimatedSprite uses a single spritesheet atlas instead, which batches much better on the GPU.
Source text
SKILL.md · MIT
---
name: pixijs-scene-gif
description: "Use this skill when displaying animated GIFs in PixiJS v8. Covers the pixi.js/gif side-effect import, Assets.load returning a GifSource, GifSprite playback (play/stop/currentFrame/animationSpeed), autoPlay/loop options, onComplete/onLoop/onFrameChange callbacks, GifSource sharing, clone, destroy. Triggers on: GifSprite, GifSource, pixi.js/gif, animationSpeed, currentFrame, autoPlay, onComplete, onFrameChange, constructor options, GifSpriteOptions."
license: MIT
---
`GifSprite` plays an animated GIF as a display object. `Assets.load('animation.gif')` returns a `GifSource` (not a `Texture`), and you wrap that in a `GifSprite`. Requires a side-effect `import 'pixi.js/gif'` to register the loader extension.
Assumes familiarity with `pixijs-scene-core-concepts`. `GifSprite` extends `Sprite`, so it is a leaf: do not nest children inside it. Wrap multiple `GifSprite` instances in a `Container` to group them.
## Quick Start
```ts
import "pixi.js/gif";
import { GifSprite } from "pixi.js/gif";
const source = await Assets.load("animation.gif");
const gif = new GifSprite({
source,
autoPlay: true,
loop: true,
animationSpeed: 1,
});
gif.anchor.set(0.5);
gif.x = app.screen.width / 2;
gif.y = app.screen.height / 2;
app.stage.addChild(gif);
```
> [!NOTE]
> GIFs decode every frame into a separate canvas texture. For performance-critical animations with many frames, prefer a spritesheet with `AnimatedSprite` — it uses a single atlas texture and batches better on the GPU.
**Related skills:** `pixijs-scene-core-concepts` (scene graph basics), `pixijs-scene-sprite` (`AnimatedSprite` for spritesheet-based animation), `pixijs-assets` (`Assets.load`, caching, unloading), `pixijs-ticker` (frame timing), `pixijs-performance` (texture memory).
## Constructor options
`GifSpriteOptions` extends `Omit<SpriteOptions, 'texture'>`; `texture` is managed internally (set from `source.textures[0]` and swapped per frame). All other `Sprite` options (`anchor`, `scale`, `tint`, `roundPixels`, etc.) are valid, and all `Container` options (`position`, `scale`, `tint`, `label`, `filters`, `zIndex`, etc.) are also valid here — see `skills/pixijs-scene-core-concepts/references/constructor-options.md`.
Leaf-specific options added by `GifSpriteOptions`:
| Option | Type | Default | Description |
| ---------------- | --------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------- |
| `source` | `GifSource` | — | Required. The parsed GIF data returned by `Assets.load('file.gif')`. Can be shared across multiple `GifSprite` instances. |
| `autoPlay` | `boolean` | `true` | Start playback immediately on construction. If `false`, you must call `gif.play()` to begin. |
| `loop` | `boolean` | `true` | Repeat the animation on reaching the last frame. When `false`, the sprite stops at the final frame and fires `onComplete`. |
| `animationSpeed` | `number` | `1` | Multiplier on the GIF's native frame timing. `2` runs at double speed; `0.5` runs at half. |
| `autoUpdate` | `boolean` | `true` | Connect playback to `Ticker.shared`. Set to `false` to drive updates yourself via `gif.update(ticker)`. |
| `fps` | `number` | `30` | Fallback frame rate for GIFs that do not specify per-frame delays. |
| `onComplete` | `() => void \| null` | `null` | Called when a non-looping animation reaches the last frame. |
| `onLoop` | `() => void \| null` | `null` | Called each time a looping animation wraps around. |
| `onFrameChange` | `(frame: number) => void \| null` | `null` | Called every time the displayed frame index changes. |
| `scaleMode` | `SCALE_MODE` | `'linear'` | Deprecated since 8.13.0 — pass `scaleMode` via `Assets.load(..., { data: { scaleMode } })` instead. |
The constructor also accepts a bare `GifSource` as its sole argument (`new GifSprite(source)`), which is shorthand for `new GifSprite({ source })` using the defaults above.
## Core Patterns
### Setup and the side-effect import
```ts
import "pixi.js/gif";
import { Assets } from "pixi.js";
import { GifSprite } from "pixi.js/gif";
const source = await Assets.load("animation.gif");
const gif = new GifSprite({ source });
```
`pixi.js/gif` calls `extensions.add(GifAsset)`, registering `.gif` with the asset loader. Without it, `Assets.load` does not recognize GIF files. `GifSprite` and `GifSource` are exported from `pixi.js/gif`, not `pixi.js`.
Importing a named export from `pixi.js/gif` also triggers the side effect, so a bare `import 'pixi.js/gif'` is only needed when you don't import anything from that path.
### Playback control
```ts
const gif = new GifSprite({ source });
gif.play();
gif.stop();
gif.currentFrame = 5;
gif.animationSpeed = 2;
gif.animationSpeed = 0.5;
gif.playing; // read-only
gif.progress; // 0-1 playback position
gif.totalFrames; // number of frames
gif.duration; // total duration in ms
```
`autoPlay: true` (default) starts playback immediately; `loop: true` (default) repeats. `animationSpeed` is a multiplier on the GIF's native frame timing. `currentFrame` is zero-based.
### Loading options
```ts
const source = await Assets.load({
src: "animation.gif",
data: {
fps: 12,
scaleMode: "nearest",
resolution: 2,
},
});
const fromDataUri = await Assets.load("data:image/gif;base64,R0lGODlh...");
```
Options in `data` are passed to `GifSource.from`. `fps` sets the fallback frame delay for GIFs that don't specify timing. `scaleMode` and `resolution` control the canvas textures created for each frame. The loader matches both `.gif` file extensions and `data:image/gif` URIs.
### Callbacks
```ts
const gif = new GifSprite({
source,
loop: false,
onComplete: () => console.log("animation finished"),
onLoop: () => console.log("loop completed"),
onFrameChange: (frame) => console.log("now on frame", frame),
});
```
- `onComplete` fires when a non-looping animation reaches the last frame.
- `onLoop` fires each time a looping animation wraps around.
- `onFrameChange` fires every time the displayed frame changes.
### Manual update mode
```ts
const gif = new GifSprite({ source, autoUpdate: false });
app.ticker.add((ticker) => {
gif.update(ticker);
});
```
`autoUpdate: false` disconnects from `Ticker.shared`. You call `gif.update(ticker)` yourself, passing any `Ticker` instance. Useful when animation should be driven by a private ticker (e.g., a pause-aware game ticker).
### Sharing source data and cloning
```ts
const source = await Assets.load("animation.gif");
const gif1 = new GifSprite({ source, autoPlay: true });
const gif2 = new GifSprite({ source, autoPlay: false });
const gif3 = gif1.clone();
gif3.animationSpeed = 0.5;
```
`GifSource` can be shared across multiple `GifSprite` instances; each sprite has independent playback state. `clone()` copies all playback settings but creates an independent instance.
## Common Mistakes
### [HIGH] Not importing pixi.js/gif
Wrong:
```ts
import { Assets } from "pixi.js";
const gif = await Assets.load("animation.gif");
```
Correct:
```ts
import "pixi.js/gif";
import { Assets } from "pixi.js";
const source = await Assets.load("animation.gif");
```
The GIF loader extension must be registered before loading. Without the side-effect import, the loader does not recognize `.gif` files and the load either fails or returns raw data.
### [MEDIUM] Expecting Assets.load to return a Texture
Wrong:
```ts
const texture = await Assets.load("animation.gif");
const sprite = new Sprite(texture);
```
Correct:
```ts
const source = await Assets.load("animation.gif");
const gif = new GifSprite({ source });
```
`Assets.load` on a GIF returns a `GifSource` containing frame textures and timing data. Pass the source to `GifSprite`; for a single still frame, read `source.textures[0]`.
### [MEDIUM] GIF memory not released on destroy
Wrong:
```ts
gif.destroy();
// GifSource and frame textures remain in memory
```
Correct:
```ts
gif.destroy(true);
// or
await Assets.unload("animation.gif");
```
GIF frames hold decoded pixel data as individual canvas textures. `gif.destroy()` (or `destroy(false)`) destroys the sprite but keeps the `GifSource` intact. Pass `true` to also destroy the source. For shared sources, only destroy when the last consumer is done, or call `Assets.unload` to let the asset cache handle it.
### [LOW] Do not nest children inside a GifSprite
`GifSprite` extends `Sprite`, which sets `allowChildren = false`. It is a leaf. To group a GIF with other display objects, wrap them all in a plain `Container`:
```ts
const group = new Container();
group.addChild(gif, label);
```
## API Reference
- [GifSprite](https://pixijs.download/release/docs/gif.GifSprite.html.md)
- [GifSpriteOptions](https://pixijs.download/release/docs/gif.GifSpriteOptions.html.md)
- [GifSource](https://pixijs.download/release/docs/gif.GifSource.html.md)
- [GifAsset](https://pixijs.download/release/docs/gif.GifAsset.html.md)
- [GifBufferOptions](https://pixijs.download/release/docs/gif.GifBufferOptions.html.md)
- [GifFrame](https://pixijs.download/release/docs/gif.GifFrame.html.md)
© pixijs · MIT · pixijs/pixijs-skills