pixijs-scene-gif
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGifSpriteAssets.load('animation.gif')GifSourceTextureGifSpriteimport 'pixi.js/gif'Assumes familiarity with . extends , so it is a leaf: do not nest children inside it. Wrap multiple instances in a to group them.
pixijs-scene-core-conceptsGifSpriteSpriteGifSpriteContainerGifSpriteAssets.load('animation.gif')GifSourceTextureGifSpriteimport 'pixi.js/gif'假设你已熟悉 。 继承自 ,因此它是叶子节点:不要在其中嵌套子元素。如需分组多个 实例,请将它们包装在 中。
pixijs-scene-core-conceptsGifSpriteSpriteGifSpriteContainerQuick 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— it uses a single atlas texture and batches better on the GPU.AnimatedSprite
Related skills: (scene graph basics), ( for spritesheet-based animation), (, caching, unloading), (frame timing), (texture memory).
pixijs-scene-core-conceptspixijs-scene-spriteAnimatedSpritepixijs-assetsAssets.loadpixijs-tickerpixijs-performancets
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] GIF会将每一帧解码为单独的画布纹理。对于性能要求高且包含大量帧的动画,建议使用带的精灵表——它使用单个图集纹理,在GPU上的批处理效果更好。AnimatedSprite
相关技能: (场景图基础)、(基于精灵表动画的 )、(、缓存、卸载)、(帧时序)、(纹理内存)。
pixijs-scene-core-conceptspixijs-scene-spriteAnimatedSpritepixijs-assetsAssets.loadpixijs-tickerpixijs-performanceConstructor options
构造函数选项
GifSpriteOptionsOmit<SpriteOptions, 'texture'>texturesource.textures[0]SpriteanchorscaletintroundPixelsContainerpositionscaletintlabelfilterszIndexskills/pixijs-scene-core-concepts/references/constructor-options.mdLeaf-specific options added by :
GifSpriteOptions| Option | Type | Default | Description |
|---|---|---|---|
| | — | Required. The parsed GIF data returned by |
| | | Start playback immediately on construction. If |
| | | Repeat the animation on reaching the last frame. When |
| | | Multiplier on the GIF's native frame timing. |
| | | Connect playback to |
| | | Fallback frame rate for GIFs that do not specify per-frame delays. |
| | | Called when a non-looping animation reaches the last frame. |
| | | Called each time a looping animation wraps around. |
| | | Called every time the displayed frame index changes. |
| | | Deprecated since 8.13.0 — pass |
The constructor also accepts a bare as its sole argument (), which is shorthand for using the defaults above.
GifSourcenew GifSprite(source)new GifSprite({ source })GifSpriteOptionsOmit<SpriteOptions, 'texture'>texturesource.textures[0]SpriteanchorscaletintroundPixelsContainerpositionscaletintlabelfilterszIndexskills/pixijs-scene-core-concepts/references/constructor-options.mdGifSpriteOptions| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | — | 必填项。 |
| | | 构造完成后立即开始播放。若设为 |
| | | 到达最后一帧时重复动画。设为 |
| | | GIF原生帧时序的乘数。设为 |
| | | 将播放连接到 |
| | | 未指定每帧延迟的GIF的 fallback 帧率。 |
| | | 非循环动画到达最后一帧时触发。 |
| | | 循环动画每次循环结束时触发。 |
| | | 显示的帧索引每次变化时触发。 |
| | | 自8.13.0版本起已废弃——请通过 |
构造函数也可仅接受一个 作为参数(),这是使用上述默认值的 的简写形式。
GifSourcenew GifSprite(source)new GifSprite({ source })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/gifextensions.add(GifAsset).gifAssets.loadGifSpriteGifSourcepixi.js/gifpixi.jsImporting a named export from also triggers the side effect, so a bare is only needed when you don't import anything from that path.
pixi.js/gifimport 'pixi.js/gif'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/gifextensions.add(GifAsset).gifAssets.loadGifSpriteGifSourcepixi.js/gifpixi.js从 导入命名导出也会触发副作用,因此只有当你不从该路径导入任何内容时,才需要单独导入 。
pixi.js/gifimport 'pixi.js/gif'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 msautoPlay: trueloop: trueanimationSpeedcurrentFramets
const gif = new GifSprite({ source });
gif.play();
gif.stop();
gif.currentFrame = 5;
gif.animationSpeed = 2;
gif.animationSpeed = 0.5;
gif.playing; // 只读
gif.progress; // 播放进度(0-1)
gif.totalFrames; // 总帧数
gif.duration; // 总时长(毫秒)autoPlay: trueloop: trueanimationSpeedcurrentFrameLoading 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 are passed to . sets the fallback frame delay for GIFs that don't specify timing. and control the canvas textures created for each frame. The loader matches both file extensions and URIs.
dataGifSource.fromfpsscaleModeresolution.gifdata:image/gifts
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...");dataGifSource.fromfpsscaleModeresolution.gifdata:image/gifCallbacks
回调函数
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),
});- fires when a non-looping animation reaches the last frame.
onComplete - fires each time a looping animation wraps around.
onLoop - fires every time the displayed frame changes.
onFrameChange
ts
const gif = new GifSprite({
source,
loop: false,
onComplete: () => console.log("动画结束"),
onLoop: () => console.log("循环完成"),
onFrameChange: (frame) => console.log("当前帧", frame),
});- :非循环动画到达最后一帧时触发。
onComplete - :循环动画每次循环结束时触发。
onLoop - :显示的帧每次变化时触发。
onFrameChange
Manual update mode
手动更新模式
ts
const gif = new GifSprite({ source, autoUpdate: false });
app.ticker.add((ticker) => {
gif.update(ticker);
});autoUpdate: falseTicker.sharedgif.update(ticker)Tickerts
const gif = new GifSprite({ source, autoUpdate: false });
app.ticker.add((ticker) => {
gif.update(ticker);
});autoUpdate: falseTicker.sharedgif.update(ticker)TickerSharing 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;GifSourceGifSpriteclone()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;GifSourceGifSpriteclone()Common Mistakes
常见错误
[HIGH] Not importing pixi.js/gif
[高风险] 未导入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 files and the load either fails or returns raw data.
.gif错误示例:
ts
import { Assets } from "pixi.js";
const gif = await Assets.load("animation.gif");正确示例:
ts
import "pixi.js/gif";
import { Assets } from "pixi.js";
const source = await Assets.load("animation.gif");必须先注册GIF加载器扩展,才能加载GIF。如果不导入副作用模块,加载器将无法识别 文件,加载操作要么失败,要么返回原始数据。
.gif[MEDIUM] Expecting Assets.load to return a Texture
[中风险] 期望Assets.load返回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.loadGifSourceGifSpritesource.textures[0]错误示例:
ts
const texture = await Assets.load("animation.gif");
const sprite = new Sprite(texture);正确示例:
ts
const source = await Assets.load("animation.gif");
const gif = new GifSprite({ source });对GIF执行 会返回包含帧纹理和时序数据的 。请将源传递给 ;如果需要单张静态帧,可读取 。
Assets.loadGifSourceGifSpritesource.textures[0][MEDIUM] GIF memory not released on destroy
[中风险] 销毁时未释放GIF内存
Wrong:
ts
gif.destroy();
// GifSource and frame textures remain in memoryCorrect:
ts
gif.destroy(true);
// or
await Assets.unload("animation.gif");GIF frames hold decoded pixel data as individual canvas textures. (or ) destroys the sprite but keeps the intact. Pass to also destroy the source. For shared sources, only destroy when the last consumer is done, or call to let the asset cache handle it.
gif.destroy()destroy(false)GifSourcetrueAssets.unload错误示例:
ts
gif.destroy();
// GifSource和帧纹理仍留在内存中正确示例:
ts
gif.destroy(true);
// 或者
await Assets.unload("animation.gif");GIF帧将解码后的像素数据存储为单独的画布纹理。(或 )会销毁精灵,但保留 完整。传入 可同时销毁源。对于共享源,仅当最后一个使用者不再需要时才销毁,或者调用 让资源缓存处理。
gif.destroy()destroy(false)GifSourcetrueAssets.unload[LOW] Do not nest children inside a GifSprite
[低风险] 不要在GifSprite中嵌套子元素
GifSpriteSpriteallowChildren = falseContainerts
const group = new Container();
group.addChild(gif, label);GifSpriteSpriteallowChildren = falseContainerts
const group = new Container();
group.addChild(gif, label);