@kurot/spine-4.2 0.1.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/README.md +154 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/kurot/EventEmitter.d.ts +23 -0
- package/dist/kurot/EventEmitter.d.ts.map +1 -0
- package/dist/kurot/EventEmitter.js +67 -0
- package/dist/kurot/EventEmitter.js.map +1 -0
- package/dist/kurot/KurotAssetManager.d.ts +26 -0
- package/dist/kurot/KurotAssetManager.d.ts.map +1 -0
- package/dist/kurot/KurotAssetManager.js +133 -0
- package/dist/kurot/KurotAssetManager.js.map +1 -0
- package/dist/kurot/KurotTexture.d.ts +16 -0
- package/dist/kurot/KurotTexture.d.ts.map +1 -0
- package/dist/kurot/KurotTexture.js +32 -0
- package/dist/kurot/KurotTexture.js.map +1 -0
- package/dist/kurot/SkeletonAnimation.d.ts +77 -0
- package/dist/kurot/SkeletonAnimation.d.ts.map +1 -0
- package/dist/kurot/SkeletonAnimation.js +176 -0
- package/dist/kurot/SkeletonAnimation.js.map +1 -0
- package/dist/kurot/SkeletonRenderer.d.ts +26 -0
- package/dist/kurot/SkeletonRenderer.d.ts.map +1 -0
- package/dist/kurot/SkeletonRenderer.js +63 -0
- package/dist/kurot/SkeletonRenderer.js.map +1 -0
- package/dist/kurot/SlotRenderer.d.ts +23 -0
- package/dist/kurot/SlotRenderer.d.ts.map +1 -0
- package/dist/kurot/SlotRenderer.js +116 -0
- package/dist/kurot/SlotRenderer.js.map +1 -0
- package/dist/kurot/Track.d.ts +99 -0
- package/dist/kurot/Track.d.ts.map +1 -0
- package/dist/kurot/Track.js +203 -0
- package/dist/kurot/Track.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @kurot/spine-4.2
|
|
2
|
+
|
|
3
|
+
Spine 4.2 runtime for the Kurot engine.
|
|
4
|
+
|
|
5
|
+
Ports the [egret-spine](https://github.com/tadazly/egret-spine) adapter to `@kurot/core`,
|
|
6
|
+
replacing Egret's `Mesh` / `Texture` / `RES` APIs with their Kurot equivalents.
|
|
7
|
+
The Spine runtime itself is provided by the official `@esotericsoftware/spine-core` npm package.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @kurot/spine-4.2
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createPlayer } from '@kurot/core';
|
|
19
|
+
import {
|
|
20
|
+
SkeletonAnimation,
|
|
21
|
+
KurotAssetManager,
|
|
22
|
+
SkeletonBinary,
|
|
23
|
+
AtlasAttachmentLoader,
|
|
24
|
+
TextureAtlas,
|
|
25
|
+
} from '@kurot/spine-4.2';
|
|
26
|
+
|
|
27
|
+
// 1. Create Kurot player
|
|
28
|
+
const app = createPlayer({ canvas, frameRate: 60, contentWidth: 640, contentHeight: 480 });
|
|
29
|
+
|
|
30
|
+
// 2. Load assets
|
|
31
|
+
const mgr = new KurotAssetManager('assets/spine/');
|
|
32
|
+
mgr.loadTextureAtlas('hero.atlas');
|
|
33
|
+
mgr.loadBinary('hero.skel');
|
|
34
|
+
|
|
35
|
+
// 3. Poll until complete
|
|
36
|
+
function waitForLoad() {
|
|
37
|
+
if (!mgr.isLoadingComplete()) {
|
|
38
|
+
requestAnimationFrame(waitForLoad);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (mgr.hasErrors()) {
|
|
42
|
+
console.error(mgr.getErrors());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 4. Build skeleton data
|
|
47
|
+
const atlas = mgr.require('hero.atlas') as TextureAtlas;
|
|
48
|
+
const binary = new SkeletonBinary(new AtlasAttachmentLoader(atlas));
|
|
49
|
+
binary.scale = 0.5;
|
|
50
|
+
const skelData = binary.readSkeletonData(mgr.require('hero.skel') as Uint8Array);
|
|
51
|
+
|
|
52
|
+
// 5. Create display object and add to stage
|
|
53
|
+
const hero = new SkeletonAnimation(skelData);
|
|
54
|
+
hero.x = 320;
|
|
55
|
+
hero.y = 480;
|
|
56
|
+
app.stage.addChild(hero);
|
|
57
|
+
app.start();
|
|
58
|
+
|
|
59
|
+
// 6. Play animations
|
|
60
|
+
hero.play('walk', 0); // loop forever
|
|
61
|
+
hero.play('attack', 1); // play once
|
|
62
|
+
hero.setMix(0.2, 'walk', 'attack'); // cross-fade
|
|
63
|
+
|
|
64
|
+
// Promise-based sequencing
|
|
65
|
+
const track = hero.start(0);
|
|
66
|
+
track.add('idle', 0);
|
|
67
|
+
await track.waitPlayEnd();
|
|
68
|
+
track.add('run', 3);
|
|
69
|
+
}
|
|
70
|
+
requestAnimationFrame(waitForLoad);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
### `SkeletonAnimation`
|
|
76
|
+
|
|
77
|
+
The main display object. Extends `Sprite` from `@kurot/core`.
|
|
78
|
+
|
|
79
|
+
| Method | Description |
|
|
80
|
+
| --------------------------------------- | ------------------------------------------------------------------- |
|
|
81
|
+
| `play(anim, loop, trackID?, listener?)` | Play an animation. `loop=0` = loop forever, `loop=N` = play N times |
|
|
82
|
+
| `playDefault(anim?, loop, trackID?)` | Play first animation if `anim` omitted |
|
|
83
|
+
| `playList(animList, loop, trackID?)` | Queue multiple animations |
|
|
84
|
+
| `playAll(loop, trackID?)` | Queue all animations in skeleton data |
|
|
85
|
+
| `playRandom(trackID?)` | Play a random animation |
|
|
86
|
+
| `start(trackID?)` | Reset pose and return a new `Track` for the given track |
|
|
87
|
+
| `stop(trackID)` | Clear a single track |
|
|
88
|
+
| `stopAll(reset?)` | Clear all tracks; optionally reset to setup pose |
|
|
89
|
+
| `setMix(time, from?, to?)` | Set cross-fade mix time |
|
|
90
|
+
| `setSkinByName(name)` | Switch skin and reset to setup pose |
|
|
91
|
+
| `getAllSkinNames()` | List all skin names |
|
|
92
|
+
| `setTimeScale(scale)` | Global time scale for all animations |
|
|
93
|
+
| `flipX` / `flipY` | Mirror the skeleton |
|
|
94
|
+
|
|
95
|
+
### `Track`
|
|
96
|
+
|
|
97
|
+
Returned by `SkeletonAnimation.start()`. Manages an animation queue on a single Spine track.
|
|
98
|
+
|
|
99
|
+
| Method | Description |
|
|
100
|
+
| ---------------------------- | ------------------------------------------------- |
|
|
101
|
+
| `add(name, loop, listener?)` | Append an animation to the queue |
|
|
102
|
+
| `setToLastFrame()` | Jump the track entry to its last frame |
|
|
103
|
+
| `waitPlayStart()` | Promise — resolves when the animation starts |
|
|
104
|
+
| `waitPlayEnd()` | Promise — resolves when all loops finish |
|
|
105
|
+
| `waitLoopStart()` | Promise — resolves at the start of each loop |
|
|
106
|
+
| `waitLoopEnd()` | Promise — resolves at the end of each loop |
|
|
107
|
+
| `waitInterrupt()` | Promise — resolves when the track is interrupted |
|
|
108
|
+
| `waitTrackEnd()` | Promise — resolves when the queue is exhausted |
|
|
109
|
+
| `waitEvent()` | Promise — resolves on the next Spine frame event |
|
|
110
|
+
| `waitNamedEvent(name)` | Promise — resolves when a named frame event fires |
|
|
111
|
+
|
|
112
|
+
### `KurotAssetManager`
|
|
113
|
+
|
|
114
|
+
Loads Spine assets using `@kurot/core`'s `HttpRequest` and `ImageLoader`.
|
|
115
|
+
|
|
116
|
+
| Method | Description |
|
|
117
|
+
| ------------------------------------------ | -------------------------------------------------- |
|
|
118
|
+
| `loadTextureAtlas(path, success?, error?)` | Load `.atlas` + page textures |
|
|
119
|
+
| `loadBinary(path, success?, error?)` | Load `.skel` binary |
|
|
120
|
+
| `loadJson(path, success?, error?)` | Load `.json` skeleton |
|
|
121
|
+
| `loadText(path, success?, error?)` | Load raw text |
|
|
122
|
+
| `isLoadingComplete()` | Returns true when all pending loads finish |
|
|
123
|
+
| `hasErrors()` | Returns true if any load failed |
|
|
124
|
+
| `getErrors()` | Map of path → error message |
|
|
125
|
+
| `require(path)` | Get a loaded asset, throws if not found |
|
|
126
|
+
| `get(path)` | Get a loaded asset, returns undefined if not found |
|
|
127
|
+
|
|
128
|
+
## Spine version compatibility
|
|
129
|
+
|
|
130
|
+
The Spine editor version must match the runtime version. This package uses
|
|
131
|
+
`@esotericsoftware/spine-core ~4.2.0` and therefore stays on the 4.2.x runtime
|
|
132
|
+
line. Export your skeletons from **Spine 4.2**.
|
|
133
|
+
|
|
134
|
+
Spine's binary and JSON formats are not guaranteed to be compatible across
|
|
135
|
+
minor runtime lines. Assets exported by another Spine version must be
|
|
136
|
+
re-exported from Spine 4.2 before they are loaded by this package.
|
|
137
|
+
|
|
138
|
+
This adapter intentionally uses the Spine 4.2 API model: `Skeleton.drawOrder`
|
|
139
|
+
is an array, slots expose `getAttachment()` and `color`, attachments expose
|
|
140
|
+
`region` and `uvs`, and clipping uses `clipTriangles()`.
|
|
141
|
+
|
|
142
|
+
## Running the example
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
pnpm example
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Opens a Vite dev server at `http://localhost:5173` with a spineboy demo.
|
|
149
|
+
Place your Spine 4.2 assets in `example/assets/`.
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT (adapter layer) — Spine runtime is © Esoteric Software LLC,
|
|
154
|
+
see [Spine Runtimes License](https://esotericsoftware.com/spine-runtimes-license).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { SkeletonAnimation } from './kurot/SkeletonAnimation.js';
|
|
2
|
+
export { SkeletonRenderer } from './kurot/SkeletonRenderer.js';
|
|
3
|
+
export { SlotRenderer } from './kurot/SlotRenderer.js';
|
|
4
|
+
export { KurotTexture } from './kurot/KurotTexture.js';
|
|
5
|
+
export { KurotAssetManager } from './kurot/KurotAssetManager.js';
|
|
6
|
+
export { Track, SpineEvent } from './kurot/Track.js';
|
|
7
|
+
export type { AnimationListener } from './kurot/Track.js';
|
|
8
|
+
export { Skeleton, SkeletonData, SkeletonJson, SkeletonBinary, AnimationState, AnimationStateData, TextureAtlas, AtlasAttachmentLoader, AssetManagerBase, Texture, TextureFilter, TextureWrap, MathUtils, Color, } from '@esotericsoftware/spine-core';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EACN,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,WAAW,EACX,SAAS,EACT,KAAK,GACL,MAAM,8BAA8B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// ── Kurot adapters ──────────────────────────────────────────────────────────
|
|
2
|
+
export { SkeletonAnimation } from './kurot/SkeletonAnimation.js';
|
|
3
|
+
export { SkeletonRenderer } from './kurot/SkeletonRenderer.js';
|
|
4
|
+
export { SlotRenderer } from './kurot/SlotRenderer.js';
|
|
5
|
+
export { KurotTexture } from './kurot/KurotTexture.js';
|
|
6
|
+
export { KurotAssetManager } from './kurot/KurotAssetManager.js';
|
|
7
|
+
export { Track } from './kurot/Track.js';
|
|
8
|
+
// ── Spine core re-exports (commonly needed by consumers) ──────────────────────
|
|
9
|
+
export { Skeleton, SkeletonData, SkeletonJson, SkeletonBinary, AnimationState, AnimationStateData, TextureAtlas, AtlasAttachmentLoader, AssetManagerBase, Texture, TextureFilter, TextureWrap, MathUtils, Color, } from '@esotericsoftware/spine-core';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAGrD,iFAAiF;AACjF,OAAO,EACN,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,WAAW,EACX,SAAS,EACT,KAAK,GACL,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic typed event emitter with no external dependencies.
|
|
3
|
+
*/
|
|
4
|
+
export declare class EventEmitter<T extends string | number> {
|
|
5
|
+
private _listeners;
|
|
6
|
+
/**
|
|
7
|
+
* Register a listener for the given event.
|
|
8
|
+
*/
|
|
9
|
+
on(event: T, fn: (...args: unknown[]) => void, ctx?: object): this;
|
|
10
|
+
/**
|
|
11
|
+
* Register a one-time listener for the given event.
|
|
12
|
+
*/
|
|
13
|
+
once(event: T, fn: (...args: unknown[]) => void, ctx?: object): this;
|
|
14
|
+
/**
|
|
15
|
+
* Remove a listener. Omitting `fn` removes all listeners for the event.
|
|
16
|
+
*/
|
|
17
|
+
off(event: T, fn?: (...args: unknown[]) => void, ctx?: object): this;
|
|
18
|
+
/**
|
|
19
|
+
* Emit an event, calling all registered listeners.
|
|
20
|
+
*/
|
|
21
|
+
emit(event: T, ...args: unknown[]): this;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=EventEmitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.d.ts","sourceRoot":"","sources":["../../src/kurot/EventEmitter.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAClD,OAAO,CAAC,UAAU,CAA4B;IAE9C;;OAEG;IACI,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAUzE;;OAEG;IACI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAU3E;;OAEG;IACI,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3E;;OAEG;IACI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAU/C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic typed event emitter with no external dependencies.
|
|
3
|
+
*/
|
|
4
|
+
export class EventEmitter {
|
|
5
|
+
_listeners = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Register a listener for the given event.
|
|
8
|
+
*/
|
|
9
|
+
on(event, fn, ctx) {
|
|
10
|
+
const list = this._listeners.get(event);
|
|
11
|
+
if (list) {
|
|
12
|
+
list.push({ fn, ctx });
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this._listeners.set(event, [{ fn, ctx }]);
|
|
16
|
+
}
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Register a one-time listener for the given event.
|
|
21
|
+
*/
|
|
22
|
+
once(event, fn, ctx) {
|
|
23
|
+
const list = this._listeners.get(event);
|
|
24
|
+
if (list) {
|
|
25
|
+
list.push({ fn, ctx, once: true });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this._listeners.set(event, [{ fn, ctx, once: true }]);
|
|
29
|
+
}
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Remove a listener. Omitting `fn` removes all listeners for the event.
|
|
34
|
+
*/
|
|
35
|
+
off(event, fn, ctx) {
|
|
36
|
+
if (fn === undefined) {
|
|
37
|
+
this._listeners.delete(event);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
const list = this._listeners.get(event);
|
|
41
|
+
if (!list)
|
|
42
|
+
return this;
|
|
43
|
+
for (let i = 0; i < list.length; i++) {
|
|
44
|
+
const it = list[i];
|
|
45
|
+
if (it.fn === fn && (ctx === undefined || it.ctx === ctx)) {
|
|
46
|
+
list.splice(i--, 1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Emit an event, calling all registered listeners.
|
|
53
|
+
*/
|
|
54
|
+
emit(event, ...args) {
|
|
55
|
+
const list = this._listeners.get(event);
|
|
56
|
+
if (!list)
|
|
57
|
+
return this;
|
|
58
|
+
for (let i = 0; i < list.length; i++) {
|
|
59
|
+
const it = list[i];
|
|
60
|
+
if (it.once)
|
|
61
|
+
list.splice(i--, 1);
|
|
62
|
+
it.fn.apply(it.ctx, args);
|
|
63
|
+
}
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=EventEmitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventEmitter.js","sourceRoot":"","sources":["../../src/kurot/EventEmitter.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,YAAY;IAChB,UAAU,GAAG,IAAI,GAAG,EAAiB,CAAC;IAE9C;;OAEG;IACI,EAAE,CAAC,KAAQ,EAAE,EAAgC,EAAE,GAAY;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,KAAQ,EAAE,EAAgC,EAAE,GAAY;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,KAAQ,EAAE,EAAiC,EAAE,GAAY;QACnE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACrB,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,KAAQ,EAAE,GAAG,IAAe;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,EAAE,CAAC,IAAI;gBAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACjC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AssetManagerBase, TextureAtlas } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { KurotTexture } from './KurotTexture.js';
|
|
3
|
+
/**
|
|
4
|
+
* Loads Spine assets (.atlas, .json, .skel, .png) using `@kurot/core`'s
|
|
5
|
+
* `HttpRequest` and `ImageLoader`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const mgr = new KurotAssetManager('assets/spine/');
|
|
10
|
+
* mgr.loadTextureAtlas('hero.atlas');
|
|
11
|
+
* mgr.loadJson('hero.json');
|
|
12
|
+
*
|
|
13
|
+
* // Poll until complete, then build skeleton:
|
|
14
|
+
* if (mgr.isLoadingComplete()) { ... }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare class KurotAssetManager extends AssetManagerBase {
|
|
18
|
+
constructor(pathPrefix?: string);
|
|
19
|
+
private get _rt();
|
|
20
|
+
loadTexture(path: string, success?: (path: string, texture: KurotTexture) => void, error?: (path: string, message: string) => void): void;
|
|
21
|
+
loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, message: string) => void): void;
|
|
22
|
+
loadJson(path: string, success?: (path: string, object: object) => void, error?: (path: string, message: string) => void): void;
|
|
23
|
+
loadBinary(path: string, success?: (path: string, binary: Uint8Array) => void, error?: (path: string, message: string) => void): void;
|
|
24
|
+
loadTextureAtlas(path: string, success?: (path: string, atlas: TextureAtlas) => void, error?: (path: string, message: string) => void): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=KurotAssetManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KurotAssetManager.d.ts","sourceRoot":"","sources":["../../src/kurot/KurotAssetManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAiBjD;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAkB,SAAQ,gBAAgB;gBAGnC,UAAU,SAAK;IAalC,OAAO,KAAK,GAAG,GAEd;IAIe,WAAW,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,EACvD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7C,IAAI;IAoBS,QAAQ,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAC9C,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7C,IAAI;IAiBS,QAAQ,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,EAChD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7C,IAAI;IAqBS,UAAU,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,EACpD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7C,IAAI;IAkBS,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,EACrD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7C,IAAI;CAiDP"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { AssetManagerBase, TextureAtlas } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { HttpRequest, HttpResponseType, ImageLoader, BitmapData, IOErrorEvent, Event } from '@kurot/core';
|
|
3
|
+
import { KurotTexture } from './KurotTexture.js';
|
|
4
|
+
/**
|
|
5
|
+
* Loads Spine assets (.atlas, .json, .skel, .png) using `@kurot/core`'s
|
|
6
|
+
* `HttpRequest` and `ImageLoader`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const mgr = new KurotAssetManager('assets/spine/');
|
|
11
|
+
* mgr.loadTextureAtlas('hero.atlas');
|
|
12
|
+
* mgr.loadJson('hero.json');
|
|
13
|
+
*
|
|
14
|
+
* // Poll until complete, then build skeleton:
|
|
15
|
+
* if (mgr.isLoadingComplete()) { ... }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export class KurotAssetManager extends AssetManagerBase {
|
|
19
|
+
// ── Constructor ───────────────────────────────────────────────────────────
|
|
20
|
+
constructor(pathPrefix = '') {
|
|
21
|
+
super((image) => {
|
|
22
|
+
const bd = new BitmapData(image);
|
|
23
|
+
if (image instanceof HTMLImageElement) {
|
|
24
|
+
bd.width = image.naturalWidth || image.width;
|
|
25
|
+
bd.height = image.naturalHeight || image.height;
|
|
26
|
+
}
|
|
27
|
+
return new KurotTexture(bd);
|
|
28
|
+
}, pathPrefix);
|
|
29
|
+
}
|
|
30
|
+
// ── Private helper ────────────────────────────────────────────────────────
|
|
31
|
+
get _rt() {
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
// ── Overrides ─────────────────────────────────────────────────────────────
|
|
35
|
+
loadTexture(path, success, error) {
|
|
36
|
+
const resolvedPath = this._rt.start(path);
|
|
37
|
+
const loader = new ImageLoader();
|
|
38
|
+
loader.addEventListener(Event.COMPLETE, () => {
|
|
39
|
+
const bd = loader.data;
|
|
40
|
+
if (!bd) {
|
|
41
|
+
this._rt.error(error ?? null, path, `Failed to load image: ${path}`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this._rt.success(success ?? null, resolvedPath, new KurotTexture(bd));
|
|
45
|
+
});
|
|
46
|
+
loader.addEventListener(IOErrorEvent.IO_ERROR, () => {
|
|
47
|
+
this._rt.error(error ?? null, path, `Couldn't load image: ${path}`);
|
|
48
|
+
});
|
|
49
|
+
loader.load(resolvedPath);
|
|
50
|
+
}
|
|
51
|
+
loadText(path, success, error) {
|
|
52
|
+
const resolvedPath = this._rt.start(path);
|
|
53
|
+
const xhr = new HttpRequest();
|
|
54
|
+
xhr.responseType = HttpResponseType.TEXT;
|
|
55
|
+
xhr.addEventListener(Event.COMPLETE, () => {
|
|
56
|
+
this._rt.success(success ?? null, resolvedPath, xhr.response);
|
|
57
|
+
});
|
|
58
|
+
xhr.addEventListener(IOErrorEvent.IO_ERROR, () => {
|
|
59
|
+
this._rt.error(error ?? null, path, `Couldn't load text: ${path}`);
|
|
60
|
+
});
|
|
61
|
+
xhr.open(resolvedPath);
|
|
62
|
+
xhr.send();
|
|
63
|
+
}
|
|
64
|
+
loadJson(path, success, error) {
|
|
65
|
+
const resolvedPath = this._rt.start(path);
|
|
66
|
+
const xhr = new HttpRequest();
|
|
67
|
+
xhr.responseType = HttpResponseType.TEXT;
|
|
68
|
+
xhr.addEventListener(Event.COMPLETE, () => {
|
|
69
|
+
try {
|
|
70
|
+
this._rt.success(success ?? null, resolvedPath, JSON.parse(xhr.response));
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
this._rt.error(error ?? null, resolvedPath, `Couldn't parse JSON ${path}: ${e.message}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
xhr.addEventListener(IOErrorEvent.IO_ERROR, () => {
|
|
77
|
+
this._rt.error(error ?? null, resolvedPath, `Couldn't load JSON: ${path}`);
|
|
78
|
+
});
|
|
79
|
+
xhr.open(resolvedPath);
|
|
80
|
+
xhr.send();
|
|
81
|
+
}
|
|
82
|
+
loadBinary(path, success, error) {
|
|
83
|
+
const resolvedPath = this._rt.start(path);
|
|
84
|
+
const xhr = new HttpRequest();
|
|
85
|
+
xhr.responseType = HttpResponseType.ARRAY_BUFFER;
|
|
86
|
+
xhr.addEventListener(Event.COMPLETE, () => {
|
|
87
|
+
const buf = xhr.response;
|
|
88
|
+
this._rt.success(success ?? null, resolvedPath, new Uint8Array(buf));
|
|
89
|
+
});
|
|
90
|
+
xhr.addEventListener(IOErrorEvent.IO_ERROR, () => {
|
|
91
|
+
this._rt.error(error ?? null, path, `Couldn't load binary: ${path}`);
|
|
92
|
+
});
|
|
93
|
+
xhr.open(resolvedPath);
|
|
94
|
+
xhr.send();
|
|
95
|
+
}
|
|
96
|
+
loadTextureAtlas(path, success, error) {
|
|
97
|
+
const resolvedPath = this._rt.start(path);
|
|
98
|
+
// parent is computed from the original path (before pathPrefix),
|
|
99
|
+
// so page image names resolve relative to the atlas file, not doubled.
|
|
100
|
+
const parent = path.lastIndexOf('/') >= 0 ? path.substring(0, path.lastIndexOf('/') + 1) : '';
|
|
101
|
+
const xhr = new HttpRequest();
|
|
102
|
+
xhr.responseType = HttpResponseType.TEXT;
|
|
103
|
+
xhr.addEventListener(Event.COMPLETE, () => {
|
|
104
|
+
try {
|
|
105
|
+
const atlas = new TextureAtlas(xhr.response);
|
|
106
|
+
let remaining = atlas.pages.length;
|
|
107
|
+
if (remaining === 0) {
|
|
108
|
+
this._rt.success(success ?? null, resolvedPath, atlas);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
for (const page of atlas.pages) {
|
|
112
|
+
this.loadTexture(parent + page.name, (_imagePath, texture) => {
|
|
113
|
+
page.setTexture(texture);
|
|
114
|
+
if (--remaining === 0) {
|
|
115
|
+
this._rt.success(success ?? null, resolvedPath, atlas);
|
|
116
|
+
}
|
|
117
|
+
}, (imagePath, message) => {
|
|
118
|
+
this._rt.error(error ?? null, imagePath, message);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
this._rt.error(error ?? null, resolvedPath, `Couldn't parse texture atlas ${path}: ${e.message}`);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
xhr.addEventListener(IOErrorEvent.IO_ERROR, () => {
|
|
127
|
+
this._rt.error(error ?? null, resolvedPath, `Couldn't load texture atlas: ${path}`);
|
|
128
|
+
});
|
|
129
|
+
xhr.open(resolvedPath);
|
|
130
|
+
xhr.send();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=KurotAssetManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KurotAssetManager.js","sourceRoot":"","sources":["../../src/kurot/KurotAssetManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Texture, TextureFilter, TextureWrap } from '@esotericsoftware/spine-core';
|
|
2
|
+
import type { BitmapData } from '@kurot/core';
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a Kurot `BitmapData` as a `spine.Texture` so the Spine runtime
|
|
5
|
+
* can reference it when building `TextureAtlas` pages.
|
|
6
|
+
*/
|
|
7
|
+
export declare class KurotTexture extends Texture {
|
|
8
|
+
readonly bitmapData: BitmapData;
|
|
9
|
+
smoothing: boolean;
|
|
10
|
+
constructor(bitmapData: BitmapData);
|
|
11
|
+
getImage(): HTMLImageElement | ImageBitmap;
|
|
12
|
+
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
|
|
13
|
+
setWraps(_uWrap: TextureWrap, _vWrap: TextureWrap): void;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=KurotTexture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KurotTexture.d.ts","sourceRoot":"","sources":["../../src/kurot/KurotTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,qBAAa,YAAa,SAAQ,OAAO;aAOL,UAAU,EAAE,UAAU;IAJlD,SAAS,UAAS;gBAIU,UAAU,EAAE,UAAU;IAMzC,QAAQ,IAAI,gBAAgB,GAAG,WAAW;IAI1C,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI;IAOpE,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAIxD,OAAO,IAAI,IAAI;CAG/B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Texture, TextureFilter } from '@esotericsoftware/spine-core';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps a Kurot `BitmapData` as a `spine.Texture` so the Spine runtime
|
|
4
|
+
* can reference it when building `TextureAtlas` pages.
|
|
5
|
+
*/
|
|
6
|
+
export class KurotTexture extends Texture {
|
|
7
|
+
bitmapData;
|
|
8
|
+
// ── Instance fields ───────────────────────────────────────────────────────
|
|
9
|
+
smoothing = false;
|
|
10
|
+
// ── Constructor ───────────────────────────────────────────────────────────
|
|
11
|
+
constructor(bitmapData) {
|
|
12
|
+
super(bitmapData.source);
|
|
13
|
+
this.bitmapData = bitmapData;
|
|
14
|
+
}
|
|
15
|
+
// ── Overrides ─────────────────────────────────────────────────────────────
|
|
16
|
+
getImage() {
|
|
17
|
+
return this.bitmapData.source;
|
|
18
|
+
}
|
|
19
|
+
setFilters(minFilter, magFilter) {
|
|
20
|
+
const { Nearest, MipMapNearestNearest } = TextureFilter;
|
|
21
|
+
this.smoothing =
|
|
22
|
+
(minFilter !== Nearest && minFilter !== MipMapNearestNearest) ||
|
|
23
|
+
(magFilter !== Nearest && magFilter !== MipMapNearestNearest);
|
|
24
|
+
}
|
|
25
|
+
setWraps(_uWrap, _vWrap) {
|
|
26
|
+
// no-op for Canvas 2D; WebGL wrap hints can be stored here if needed
|
|
27
|
+
}
|
|
28
|
+
dispose() {
|
|
29
|
+
this.bitmapData.dispose();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=KurotTexture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KurotTexture.js","sourceRoot":"","sources":["../../src/kurot/KurotTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAe,MAAM,8BAA8B,CAAC;AAGnF;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,OAAO;IAOL;IANnC,6EAA6E;IAEtE,SAAS,GAAG,KAAK,CAAC;IAEzB,6EAA6E;IAE7E,YAAmC,UAAsB;QACxD,KAAK,CAAC,UAAU,CAAC,MAA0B,CAAC,CAAC;QADX,eAAU,GAAV,UAAU,CAAY;IAEzD,CAAC;IAED,6EAA6E;IAE7D,QAAQ;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,MAA0B,CAAC;IACnD,CAAC;IAEe,UAAU,CAAC,SAAwB,EAAE,SAAwB;QAC5E,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,aAAa,CAAC;QACxD,IAAI,CAAC,SAAS;YACb,CAAC,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,oBAAoB,CAAC;gBAC7D,CAAC,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,oBAAoB,CAAC,CAAC;IAChE,CAAC;IAEe,QAAQ,CAAC,MAAmB,EAAE,MAAmB;QAChE,qEAAqE;IACtE,CAAC;IAEe,OAAO;QACtB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { AnimationState, AnimationStateData, Skeleton, type SkeletonData as SpineSkeletonData } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { Sprite } from '@kurot/core';
|
|
3
|
+
import type { Stage } from '@kurot/core';
|
|
4
|
+
import { SkeletonRenderer } from './SkeletonRenderer.js';
|
|
5
|
+
import { Track } from './Track.js';
|
|
6
|
+
import type { AnimationListener } from './Track.js';
|
|
7
|
+
export declare class SkeletonAnimation extends Sprite {
|
|
8
|
+
readonly renderer: SkeletonRenderer;
|
|
9
|
+
private _lastTime;
|
|
10
|
+
constructor(skeletonData: SpineSkeletonData);
|
|
11
|
+
get skeleton(): Skeleton;
|
|
12
|
+
get skeletonData(): SpineSkeletonData;
|
|
13
|
+
get state(): AnimationState;
|
|
14
|
+
get stateData(): AnimationStateData;
|
|
15
|
+
get flipX(): boolean;
|
|
16
|
+
set flipX(v: boolean);
|
|
17
|
+
get flipY(): boolean;
|
|
18
|
+
set flipY(v: boolean);
|
|
19
|
+
/**
|
|
20
|
+
* Set the global time scale for all animations on this skeleton.
|
|
21
|
+
*/
|
|
22
|
+
setTimeScale(scale: number): void;
|
|
23
|
+
/**
|
|
24
|
+
* Set the cross-fade mix time between two animations.
|
|
25
|
+
* Omit both names to set the default mix for all transitions.
|
|
26
|
+
*/
|
|
27
|
+
setMix(mixTime: number, fromAnim?: string, toAnim?: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Return all skin names defined in the skeleton data.
|
|
30
|
+
*/
|
|
31
|
+
getAllSkinNames(): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Switch to the named skin and reset the skeleton to its setup pose.
|
|
34
|
+
*/
|
|
35
|
+
setSkinByName(name: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Play a single animation.
|
|
38
|
+
* @param anim Animation name.
|
|
39
|
+
* @param loop Number of times to play. 0 = loop forever.
|
|
40
|
+
* @param trackID Spine track index (default 0).
|
|
41
|
+
* @param listener Optional lifecycle callbacks.
|
|
42
|
+
*/
|
|
43
|
+
play(anim: string, loop?: number, trackID?: number, listener?: AnimationListener): Track;
|
|
44
|
+
/**
|
|
45
|
+
* Play the first animation in the skeleton data, or a named one.
|
|
46
|
+
*/
|
|
47
|
+
playDefault(anim?: string, loop?: number, trackID?: number, listener?: AnimationListener): Track;
|
|
48
|
+
/**
|
|
49
|
+
* Queue a list of animations on the given track.
|
|
50
|
+
*/
|
|
51
|
+
playList(animList: string[], loop?: number, trackID?: number): Track;
|
|
52
|
+
/**
|
|
53
|
+
* Queue all animations defined in the skeleton data.
|
|
54
|
+
*/
|
|
55
|
+
playAll(loop?: number, trackID?: number): Track;
|
|
56
|
+
/**
|
|
57
|
+
* Play a randomly chosen animation.
|
|
58
|
+
*/
|
|
59
|
+
playRandom(trackID?: number): Track;
|
|
60
|
+
/**
|
|
61
|
+
* Reset the skeleton to its setup pose and return a new Track for the given track ID.
|
|
62
|
+
*/
|
|
63
|
+
start(trackID?: number): Track;
|
|
64
|
+
/**
|
|
65
|
+
* Clear a single animation track.
|
|
66
|
+
*/
|
|
67
|
+
stop(trackID: number): void;
|
|
68
|
+
/**
|
|
69
|
+
* Clear all animation tracks.
|
|
70
|
+
* @param reset If true, also resets the skeleton to its setup pose.
|
|
71
|
+
*/
|
|
72
|
+
stopAll(reset?: boolean): void;
|
|
73
|
+
$onAddToStage(stage: Stage, $nestLevel: number): void;
|
|
74
|
+
$onRemoveFromStage(): void;
|
|
75
|
+
private _handleEnterFrame;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=SkeletonAnimation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkeletonAnimation.d.ts","sourceRoot":"","sources":["../../src/kurot/SkeletonAnimation.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,KAAK,YAAY,IAAI,iBAAiB,EACtC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAS,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAuBpD,qBAAa,iBAAkB,SAAQ,MAAM;IAC5C,SAAgB,QAAQ,EAAE,gBAAgB,CAAC;IAE3C,OAAO,CAAC,SAAS,CAAK;gBAEH,YAAY,EAAE,iBAAiB;IAQlD,IAAW,QAAQ,IAAI,QAAQ,CAE9B;IACD,IAAW,YAAY,IAAI,iBAAiB,CAE3C;IACD,IAAW,KAAK,IAAI,cAAc,CAEjC;IACD,IAAW,SAAS,IAAI,kBAAkB,CAEzC;IAID,IAAW,KAAK,IAAI,OAAO,CAE1B;IACD,IAAW,KAAK,CAAC,CAAC,EAAE,OAAO,EAE1B;IAED,IAAW,KAAK,IAAI,OAAO,CAE1B;IACD,IAAW,KAAK,CAAC,CAAC,EAAE,OAAO,EAE1B;IAID;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxC;;;OAGG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAQxE;;OAEG;IACI,eAAe,IAAI,MAAM,EAAE;IAIlC;;OAEG;IACI,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxC;;;;;;OAMG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAI,EAAE,OAAO,SAAI,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,KAAK;IAIrF;;OAEG;IACI,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,SAAI,EAAE,OAAO,SAAI,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,KAAK;IAK7F;;OAEG;IACI,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,SAAI,EAAE,OAAO,SAAI,GAAG,KAAK;IAQjE;;OAEG;IACI,OAAO,CAAC,IAAI,SAAI,EAAE,OAAO,SAAI,GAAG,KAAK;IAQ5C;;OAEG;IACI,UAAU,CAAC,OAAO,SAAI,GAAG,KAAK;IAMrC;;OAEG;IACI,KAAK,CAAC,OAAO,SAAI,GAAG,KAAK;IAKhC;;OAEG;IACI,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;;OAGG;IACI,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAOrB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAMrD,kBAAkB,IAAI,IAAI;IAO1C,OAAO,CAAC,iBAAiB,CAIvB;CACF"}
|