@spritebuddy/pixi 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +57 -2
- package/dist/index.d.ts +86 -0
- package/dist/index.js +205 -0
- package/dist/index.js.map +1 -0
- package/dist/pixi-types.d.ts +25 -0
- package/dist/pixi-types.js +2 -0
- package/dist/pixi-types.js.map +1 -0
- package/package.json +54 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Patrick Hammond
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,58 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @spritebuddy/pixi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Play [SpriteBuddy](https://github.com/Patrick-Hammond/spritebuddy) animations in **PixiJS 5.3+,
|
|
4
|
+
6, 7 and 8** with one package: per-frame timing, loop, ping-pong and play-once, frame offsets,
|
|
5
|
+
and layers drawn live (export with "Play layers live" so the sheet holds each frame once).
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @spritebuddy/pixi
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import * as PIXI from 'pixi.js';
|
|
13
|
+
import { spriteBuddy } from '@spritebuddy/pixi';
|
|
14
|
+
|
|
15
|
+
const sb = spriteBuddy(PIXI); // pass your PixiJS in: that is how one package serves 5 to 8
|
|
16
|
+
|
|
17
|
+
const knight = await sb.load('assets/knight.anims.json'); // loads knight.png beside it
|
|
18
|
+
const hero = knight.sprite('walk'); // a Container whose origin is the character's pivot
|
|
19
|
+
hero.x = 200;
|
|
20
|
+
hero.y = 300;
|
|
21
|
+
app.stage.addChild(hero);
|
|
22
|
+
|
|
23
|
+
hero.onComplete = () => hero.play('idle'); // for "once" animations
|
|
24
|
+
hero.on('event:hit', () => enemy.takeHit()); // an event tagged on a frame in SpriteBuddy
|
|
25
|
+
hero.play('attack');
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The sprite's origin is where the character stands (the frame's pivot), so `x` and `y` put its
|
|
29
|
+
feet on the ground. Scale it up for pixel art: `hero.scale.set(4)`.
|
|
30
|
+
|
|
31
|
+
With PixiJS 7 or 8 you can use `Assets` instead:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
PIXI.extensions.add(sb.assetsParser);
|
|
35
|
+
const knight = await PIXI.Assets.load('assets/knight.anims.json'); // a SpriteBuddySheet
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The [PixiJS example](https://github.com/Patrick-Hammond/spritebuddy-runtimes/tree/main/examples/pixi) is a complete page: three slimes from one
|
|
39
|
+
sheet, one wearing a hat drawn as a live layer, and a hop on click.
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
- `sb.load(url, { pixelArt })` loads a runtime file and its image. `pixelArt` (default `true`)
|
|
44
|
+
turns on nearest-neighbour sampling.
|
|
45
|
+
- `sb.sheet(json, texture)` makes a sheet from a file and an image you loaded yourself.
|
|
46
|
+
- `sheet.sprite(animation?, { autoPlay, autoUpdate, speed })` makes an animated sprite.
|
|
47
|
+
`sheet.textures`, `sheet.texture(name)` and `sheet.animations` are there too.
|
|
48
|
+
- A sprite has `play(name, time?)`, `stop()`, `seek(ms)`, `update(ms)`, `speed`, `playing`,
|
|
49
|
+
`animation`, `onFrame`, `onEvent` and `onComplete`. It moves on with `Ticker.shared` unless you set
|
|
50
|
+
`autoUpdate = false` and call `update(ms)` yourself.
|
|
51
|
+
- Frame events: as a frame tagged with events starts showing, the sprite calls
|
|
52
|
+
`onEvent(name, index)` and emits `"event"` (name, index) and `"event:<name>"` (index) on its
|
|
53
|
+
PixiJS event emitter, so `hero.on('event:step', playFootstep)` works.
|
|
54
|
+
|
|
55
|
+
Every PixiJS version is tested by rendering the shared fixtures in Chromium and comparing each
|
|
56
|
+
pixel with a software render of the format's rules.
|
|
57
|
+
|
|
58
|
+
Licence: ISC.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Player, type SpriteBuddyFile } from '@spritebuddy/core';
|
|
2
|
+
import type { PixiNamespace, PixiTexture } from './pixi-types.js';
|
|
3
|
+
export type { PixiNamespace } from './pixi-types.js';
|
|
4
|
+
export interface SheetOptions {
|
|
5
|
+
/** Nearest-neighbour sampling, so pixel art stays crisp when scaled. Defaults to true. */
|
|
6
|
+
readonly pixelArt?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SpriteOptions {
|
|
9
|
+
/** Starts playing at once. Defaults to true. */
|
|
10
|
+
readonly autoPlay?: boolean;
|
|
11
|
+
/** Moves on with PixiJS's shared ticker. Defaults to true; turn off to call `update` yourself. */
|
|
12
|
+
readonly autoUpdate?: boolean;
|
|
13
|
+
/** Playback rate: 1 is normal. */
|
|
14
|
+
readonly speed?: number;
|
|
15
|
+
}
|
|
16
|
+
/** A loaded runtime file: one PixiJS texture per frame, ready to make sprites from. */
|
|
17
|
+
export interface SpriteBuddySheet {
|
|
18
|
+
readonly file: SpriteBuddyFile;
|
|
19
|
+
/** One texture per frame, in file order. */
|
|
20
|
+
readonly textures: readonly PixiTexture[];
|
|
21
|
+
/** Animation names, in file order. */
|
|
22
|
+
readonly animations: readonly string[];
|
|
23
|
+
/** The texture of the frame called `name`. */
|
|
24
|
+
texture(name: string): PixiTexture | undefined;
|
|
25
|
+
/** A new animated sprite, playing `animation` (default: the first one). */
|
|
26
|
+
sprite(animation?: string, options?: SpriteOptions): SpriteBuddySprite;
|
|
27
|
+
/** Destroys the frame textures and the sheet image. */
|
|
28
|
+
destroy(): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* An animated sprite: a container whose origin is where the character stands (the frame pivot).
|
|
32
|
+
* It draws the current frame and its layers as child sprites.
|
|
33
|
+
*/
|
|
34
|
+
export interface SpriteBuddySprite {
|
|
35
|
+
readonly sheet: SpriteBuddySheet;
|
|
36
|
+
readonly player: Player;
|
|
37
|
+
/** The animation playing (or last played). */
|
|
38
|
+
readonly animation: string | null;
|
|
39
|
+
readonly playing: boolean;
|
|
40
|
+
speed: number;
|
|
41
|
+
/** Called with the frame index each time the frame changes. */
|
|
42
|
+
onFrame: ((index: number) => void) | null;
|
|
43
|
+
/** Called when a `once` animation ends. */
|
|
44
|
+
onComplete: (() => void) | null;
|
|
45
|
+
/**
|
|
46
|
+
* Called for each frame event (such as `"hit"`) as its frame starts showing, with the frame's
|
|
47
|
+
* index in the animation. The sprite also emits `"event"` (name, index) and `"event:<name>"`
|
|
48
|
+
* (index), so `sprite.on('event:hit', ...)` works too.
|
|
49
|
+
*/
|
|
50
|
+
onEvent: ((name: string, index: number) => void) | null;
|
|
51
|
+
play(animation: string, time?: number): this;
|
|
52
|
+
stop(): this;
|
|
53
|
+
/** Jumps to `ms` into the animation. */
|
|
54
|
+
seek(ms: number): this;
|
|
55
|
+
/** Moves time on by `ms` and redraws (called for you while `autoUpdate` is on). */
|
|
56
|
+
update(ms: number): this;
|
|
57
|
+
autoUpdate: boolean;
|
|
58
|
+
destroy(options?: unknown): void;
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
readonly children: readonly unknown[];
|
|
62
|
+
/** PixiJS's event emitter, typed loosely so any PixiJS version fits. */
|
|
63
|
+
on(event: string, listener: (...args: any[]) => void, context?: unknown): this;
|
|
64
|
+
off(event: string, listener?: (...args: any[]) => void, context?: unknown): this;
|
|
65
|
+
}
|
|
66
|
+
/** What `spriteBuddy(PIXI)` returns. */
|
|
67
|
+
export interface SpriteBuddyPixi {
|
|
68
|
+
/** Loads a runtime file and its image. Works in every supported PixiJS version. */
|
|
69
|
+
load(url: string, options?: SheetOptions): Promise<SpriteBuddySheet>;
|
|
70
|
+
/** Makes a sheet from a parsed (or raw) runtime file and its already loaded image. */
|
|
71
|
+
sheet(file: SpriteBuddyFile | unknown, image: PixiTexture, options?: SheetOptions): SpriteBuddySheet;
|
|
72
|
+
/**
|
|
73
|
+
* PixiJS 7 and 8: an Assets loader extension, so `Assets.load('hero.anims.json')` resolves to
|
|
74
|
+
* a {@link SpriteBuddySheet}. Add it once with `extensions.add(sb.assetsParser)`.
|
|
75
|
+
*/
|
|
76
|
+
readonly assetsParser: object;
|
|
77
|
+
/** Major PixiJS version detected: 5 or 6 (one code path), 7 or 8. */
|
|
78
|
+
readonly version: number;
|
|
79
|
+
}
|
|
80
|
+
/** The image's URL next to the runtime file's. */
|
|
81
|
+
export declare function siblingUrl(fileUrl: string, image: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Binds SpriteBuddy to your PixiJS: `const sb = spriteBuddy(PIXI)`. Passing the namespace in
|
|
84
|
+
* (rather than importing `pixi.js` here) lets one package serve PixiJS 5 through 8.
|
|
85
|
+
*/
|
|
86
|
+
export declare function spriteBuddy(PIXI: PixiNamespace): SpriteBuddyPixi;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
import { FORMAT, parseFile, Player } from '@spritebuddy/core';
|
|
13
|
+
const isFile = (v) => typeof v === 'object' && v !== null && 'animations' in v && 'width' in v && !('format' in v);
|
|
14
|
+
/** The image's URL next to the runtime file's. */
|
|
15
|
+
export function siblingUrl(fileUrl, image) {
|
|
16
|
+
if (/^([a-z][a-z0-9+.-]*:|\/)/i.test(image))
|
|
17
|
+
return image;
|
|
18
|
+
return fileUrl.replace(/[?#].*$/, '').replace(/[^/]*$/, '') + image;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Binds SpriteBuddy to your PixiJS: `const sb = spriteBuddy(PIXI)`. Passing the namespace in
|
|
22
|
+
* (rather than importing `pixi.js` here) lets one package serve PixiJS 5 through 8.
|
|
23
|
+
*/
|
|
24
|
+
export function spriteBuddy(PIXI) {
|
|
25
|
+
var _SpriteClass_instances, _SpriteClass_pool, _SpriteClass_auto, _SpriteClass_tick, _SpriteClass_draw;
|
|
26
|
+
const v8 = typeof PIXI.TextureSource === 'function';
|
|
27
|
+
const version = v8 ? 8 : typeof PIXI.Assets === 'object' ? 7 : 6;
|
|
28
|
+
const baseOf = (texture) => (v8 ? texture.source : texture.baseTexture);
|
|
29
|
+
function setNearest(texture) {
|
|
30
|
+
const base = baseOf(texture);
|
|
31
|
+
if (!base)
|
|
32
|
+
return;
|
|
33
|
+
base.scaleMode = v8 ? 'nearest' : (PIXI.SCALE_MODES?.NEAREST ?? 0);
|
|
34
|
+
}
|
|
35
|
+
function frameTexture(base, f) {
|
|
36
|
+
const R = PIXI.Rectangle;
|
|
37
|
+
const { x, y, w, h } = f.rect;
|
|
38
|
+
const frame = f.rotated ? new R(x, y, h, w) : new R(x, y, w, h);
|
|
39
|
+
const orig = new R(0, 0, f.width, f.height);
|
|
40
|
+
const trim = f.trim ? new R(f.trim.x, f.trim.y, w, h) : undefined;
|
|
41
|
+
// TexturePacker's "rotated" (90° clockwise on the sheet) is PixiJS's groupD8 rotation 2.
|
|
42
|
+
const rotate = f.rotated ? 2 : 0;
|
|
43
|
+
return v8
|
|
44
|
+
? new PIXI.Texture({ source: base, frame, orig, trim, rotate, label: f.name })
|
|
45
|
+
: new PIXI.Texture(base, frame, orig, trim, rotate);
|
|
46
|
+
}
|
|
47
|
+
function makeSheet(raw, image, options = {}) {
|
|
48
|
+
const file = isFile(raw) ? raw : parseFile(raw);
|
|
49
|
+
if (options.pixelArt !== false)
|
|
50
|
+
setNearest(image);
|
|
51
|
+
const base = baseOf(image);
|
|
52
|
+
const textures = file.frames.map((f) => frameTexture(base, f));
|
|
53
|
+
const sheet = {
|
|
54
|
+
file,
|
|
55
|
+
textures,
|
|
56
|
+
animations: file.animations.map((a) => a.name),
|
|
57
|
+
texture: (name) => textures[file.frames.findIndex((f) => f.name === name)],
|
|
58
|
+
sprite: (animation, spriteOptions) => new SpriteClass(sheet, animation, spriteOptions),
|
|
59
|
+
destroy() {
|
|
60
|
+
for (const t of textures)
|
|
61
|
+
t.destroy(false);
|
|
62
|
+
image.destroy(true);
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
return sheet;
|
|
66
|
+
}
|
|
67
|
+
const Container = PIXI.Container;
|
|
68
|
+
class SpriteClass extends Container {
|
|
69
|
+
constructor(sheet, animation, options = {}) {
|
|
70
|
+
super();
|
|
71
|
+
_SpriteClass_instances.add(this);
|
|
72
|
+
this.onFrame = null;
|
|
73
|
+
this.onComplete = null;
|
|
74
|
+
this.onEvent = null;
|
|
75
|
+
_SpriteClass_pool.set(this, []);
|
|
76
|
+
_SpriteClass_auto.set(this, false);
|
|
77
|
+
_SpriteClass_tick.set(this, () => this.update(PIXI.Ticker.shared.deltaMS));
|
|
78
|
+
this.sheet = sheet;
|
|
79
|
+
this.player = new Player(sheet.file, {
|
|
80
|
+
onFrame: (i) => this.onFrame?.(i),
|
|
81
|
+
onComplete: () => this.onComplete?.(),
|
|
82
|
+
onEvent: (name, index) => {
|
|
83
|
+
this.onEvent?.(name, index);
|
|
84
|
+
this.emit?.('event', name, index);
|
|
85
|
+
this.emit?.(`event:${name}`, index);
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
if (options.speed !== undefined)
|
|
89
|
+
this.player.speed = options.speed;
|
|
90
|
+
const first = animation ?? sheet.animations[0];
|
|
91
|
+
if (first !== undefined) {
|
|
92
|
+
this.player.play(first);
|
|
93
|
+
if (options.autoPlay === false)
|
|
94
|
+
this.player.stop();
|
|
95
|
+
__classPrivateFieldGet(this, _SpriteClass_instances, "m", _SpriteClass_draw).call(this);
|
|
96
|
+
}
|
|
97
|
+
this.autoUpdate = options.autoUpdate !== false;
|
|
98
|
+
}
|
|
99
|
+
get animation() {
|
|
100
|
+
return this.player.state.animation?.name ?? null;
|
|
101
|
+
}
|
|
102
|
+
get playing() {
|
|
103
|
+
return this.player.playing;
|
|
104
|
+
}
|
|
105
|
+
get speed() {
|
|
106
|
+
return this.player.speed;
|
|
107
|
+
}
|
|
108
|
+
set speed(value) {
|
|
109
|
+
this.player.speed = value;
|
|
110
|
+
}
|
|
111
|
+
get autoUpdate() {
|
|
112
|
+
return __classPrivateFieldGet(this, _SpriteClass_auto, "f");
|
|
113
|
+
}
|
|
114
|
+
set autoUpdate(on) {
|
|
115
|
+
if (on === __classPrivateFieldGet(this, _SpriteClass_auto, "f"))
|
|
116
|
+
return;
|
|
117
|
+
__classPrivateFieldSet(this, _SpriteClass_auto, on, "f");
|
|
118
|
+
if (on)
|
|
119
|
+
PIXI.Ticker.shared.add(__classPrivateFieldGet(this, _SpriteClass_tick, "f"));
|
|
120
|
+
else
|
|
121
|
+
PIXI.Ticker.shared.remove(__classPrivateFieldGet(this, _SpriteClass_tick, "f"));
|
|
122
|
+
}
|
|
123
|
+
play(animation, time = 0) {
|
|
124
|
+
this.player.play(animation, time);
|
|
125
|
+
__classPrivateFieldGet(this, _SpriteClass_instances, "m", _SpriteClass_draw).call(this);
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
stop() {
|
|
129
|
+
this.player.stop();
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
seek(ms) {
|
|
133
|
+
this.player.seek(ms);
|
|
134
|
+
__classPrivateFieldGet(this, _SpriteClass_instances, "m", _SpriteClass_draw).call(this);
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
update(ms) {
|
|
138
|
+
if (!this.player.playing)
|
|
139
|
+
return this;
|
|
140
|
+
this.player.update(ms);
|
|
141
|
+
__classPrivateFieldGet(this, _SpriteClass_instances, "m", _SpriteClass_draw).call(this);
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
destroy(options) {
|
|
145
|
+
this.autoUpdate = false;
|
|
146
|
+
super.destroy(options);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
_SpriteClass_pool = new WeakMap(), _SpriteClass_auto = new WeakMap(), _SpriteClass_tick = new WeakMap(), _SpriteClass_instances = new WeakSet(), _SpriteClass_draw = function _SpriteClass_draw() {
|
|
150
|
+
const parts = this.player.parts;
|
|
151
|
+
while (__classPrivateFieldGet(this, _SpriteClass_pool, "f").length < parts.length) {
|
|
152
|
+
const s = new PIXI.Sprite(PIXI.Texture.EMPTY);
|
|
153
|
+
__classPrivateFieldGet(this, _SpriteClass_pool, "f").push(s);
|
|
154
|
+
this.addChild(s);
|
|
155
|
+
}
|
|
156
|
+
__classPrivateFieldGet(this, _SpriteClass_pool, "f").forEach((s, i) => {
|
|
157
|
+
const part = parts[i];
|
|
158
|
+
s.visible = !!part;
|
|
159
|
+
if (!part)
|
|
160
|
+
return;
|
|
161
|
+
s.texture = this.sheet.textures[part.index];
|
|
162
|
+
s.alpha = part.opacity;
|
|
163
|
+
s.scale.x = part.flipX ? -1 : 1;
|
|
164
|
+
s.scale.y = part.flipY ? -1 : 1;
|
|
165
|
+
s.x = part.x + (part.flipX ? part.frame.width : 0);
|
|
166
|
+
s.y = part.y + (part.flipY ? part.frame.height : 0);
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
async function loadImage(url) {
|
|
170
|
+
if (PIXI.Assets)
|
|
171
|
+
return PIXI.Assets.load(url);
|
|
172
|
+
return PIXI.Texture.fromURL(url);
|
|
173
|
+
}
|
|
174
|
+
const LOAD_PARSER = PIXI.ExtensionType?.LoadParser ?? 'load-parser';
|
|
175
|
+
return {
|
|
176
|
+
version,
|
|
177
|
+
sheet: makeSheet,
|
|
178
|
+
async load(url, options) {
|
|
179
|
+
const response = await fetch(url);
|
|
180
|
+
if (!response.ok)
|
|
181
|
+
throw new Error(`Couldn't load ${url}: ${response.status}`);
|
|
182
|
+
const file = parseFile(await response.json());
|
|
183
|
+
return makeSheet(file, await loadImage(siblingUrl(url, file.image)), options);
|
|
184
|
+
},
|
|
185
|
+
assetsParser: {
|
|
186
|
+
name: 'spritebuddy',
|
|
187
|
+
// Before PixiJS's own spritesheet parser, which would take any JSON with `frames`.
|
|
188
|
+
extension: { type: LOAD_PARSER, priority: 2, name: 'spritebuddy' },
|
|
189
|
+
async testParse(asset) {
|
|
190
|
+
return (typeof asset === 'object' &&
|
|
191
|
+
asset !== null &&
|
|
192
|
+
asset.format === FORMAT);
|
|
193
|
+
},
|
|
194
|
+
async parse(asset, resolved, loader) {
|
|
195
|
+
const file = parseFile(asset);
|
|
196
|
+
const image = await loader.load(siblingUrl(resolved?.src ?? '', file.image));
|
|
197
|
+
return makeSheet(file, image);
|
|
198
|
+
},
|
|
199
|
+
async unload(sheet) {
|
|
200
|
+
sheet.destroy();
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts of a PixiJS namespace this package uses, typed loosely so that `import * as PIXI
|
|
3
|
+
* from 'pixi.js'` fits for PixiJS 5, 6, 7 and 8.
|
|
4
|
+
*/
|
|
5
|
+
export interface PixiTexture {
|
|
6
|
+
/** PixiJS 8. */
|
|
7
|
+
readonly source?: unknown;
|
|
8
|
+
/** PixiJS 5 to 7. */
|
|
9
|
+
readonly baseTexture?: unknown;
|
|
10
|
+
destroy(destroyBase?: boolean): void;
|
|
11
|
+
}
|
|
12
|
+
export interface PixiNamespace {
|
|
13
|
+
readonly Container: any;
|
|
14
|
+
readonly Sprite: any;
|
|
15
|
+
readonly Texture: any;
|
|
16
|
+
readonly Rectangle: any;
|
|
17
|
+
readonly Ticker: any;
|
|
18
|
+
/** PixiJS 8 only; used to tell versions apart. */
|
|
19
|
+
readonly TextureSource?: any;
|
|
20
|
+
/** PixiJS 7 and 8. */
|
|
21
|
+
readonly Assets?: any;
|
|
22
|
+
readonly ExtensionType?: any;
|
|
23
|
+
/** PixiJS 5 to 7. */
|
|
24
|
+
readonly SCALE_MODES?: any;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pixi-types.js","sourceRoot":"","sources":["../src/pixi-types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spritebuddy/pixi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Play SpriteBuddy animations in PixiJS 5, 6, 7 and 8: per-frame timing, offsets and live layers.",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"author": "Patrick Hammond",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Patrick-Hammond/spritebuddy-runtimes.git",
|
|
10
|
+
"directory": "packages/pixi"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"spritebuddy",
|
|
14
|
+
"pixi",
|
|
15
|
+
"pixijs",
|
|
16
|
+
"spritesheet",
|
|
17
|
+
"animation",
|
|
18
|
+
"gamedev"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@spritebuddy/core": "^0.2.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"pixi.js": ">=5.3.0 <9"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"pixi.js": {
|
|
42
|
+
"optional": true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"pixi5": "npm:pixi.js@5.3.12",
|
|
47
|
+
"pixi6": "npm:pixi.js@6.5.10",
|
|
48
|
+
"pixi7": "npm:pixi.js@7.4.3",
|
|
49
|
+
"pixi8": "npm:pixi.js@8.22.0"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc -p tsconfig.build.json",
|
|
53
|
+
"prepack": "npm run build",
|
|
54
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
55
|
+
}
|
|
56
|
+
}
|