@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 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).
@@ -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"}