@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
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Sprite, Event } from '@kurot/core';
|
|
2
|
+
import { SkeletonRenderer } from './SkeletonRenderer.js';
|
|
3
|
+
import { Track } from './Track.js';
|
|
4
|
+
// The main public-facing display object for Spine animations.
|
|
5
|
+
//
|
|
6
|
+
// Implementation notes:
|
|
7
|
+
// - extends Sprite from @kurot/core
|
|
8
|
+
// - Constructor receives a spine.SkeletonData:
|
|
9
|
+
// 1. Create a SkeletonRenderer and addChild()
|
|
10
|
+
// 2. Expose renderer.state / stateData / skeleton / skeletonData as readonly
|
|
11
|
+
// - Lifecycle:
|
|
12
|
+
// - $onAddToStage(): record lastTime, register ENTER_FRAME listener
|
|
13
|
+
// - $onRemoveFromStage(): remove ENTER_FRAME listener
|
|
14
|
+
// - ENTER_FRAME handler: renderer.update(now - lastTime); lastTime = now
|
|
15
|
+
// - flipX / flipY: set renderer.scaleX / scaleY (Spine Y is already inverted in renderer)
|
|
16
|
+
// - setTimeScale(scale): state.timeScale = scale
|
|
17
|
+
// - setMix(mixTime, fromAnim?, toAnim?): stateData.setMix() or defaultMix
|
|
18
|
+
// - getAllSkinNames(): skeletonData.skins.map(s => s.name)
|
|
19
|
+
// - setSkinByName(name): skeleton.setSkinByName(); skeleton.setSlotsToSetupPose()
|
|
20
|
+
// - play(anim, loop, trackID, listener): start(trackID).add(anim, loop, listener)
|
|
21
|
+
// - start(trackID): skeleton.setToSetupPose(); return new Track(this, trackID)
|
|
22
|
+
// - stop(track): state.clearTrack(track)
|
|
23
|
+
// - stopAll(reset?): state.clearTracks(); if reset: skeleton.setToSetupPose()
|
|
24
|
+
export class SkeletonAnimation extends Sprite {
|
|
25
|
+
renderer;
|
|
26
|
+
_lastTime = 0;
|
|
27
|
+
constructor(skeletonData) {
|
|
28
|
+
super();
|
|
29
|
+
this.renderer = new SkeletonRenderer(skeletonData);
|
|
30
|
+
this.addChild(this.renderer);
|
|
31
|
+
}
|
|
32
|
+
// ── Getters ───────────────────────────────────────────────────────────────
|
|
33
|
+
get skeleton() {
|
|
34
|
+
return this.renderer.skeleton;
|
|
35
|
+
}
|
|
36
|
+
get skeletonData() {
|
|
37
|
+
return this.renderer.skeletonData;
|
|
38
|
+
}
|
|
39
|
+
get state() {
|
|
40
|
+
return this.renderer.state;
|
|
41
|
+
}
|
|
42
|
+
get stateData() {
|
|
43
|
+
return this.renderer.stateData;
|
|
44
|
+
}
|
|
45
|
+
// ── Flip ──────────────────────────────────────────────────────────────────
|
|
46
|
+
get flipX() {
|
|
47
|
+
return this.renderer.scaleX === -1;
|
|
48
|
+
}
|
|
49
|
+
set flipX(v) {
|
|
50
|
+
this.renderer.scaleX = v ? -1 : 1;
|
|
51
|
+
}
|
|
52
|
+
get flipY() {
|
|
53
|
+
return this.renderer.scaleY === 1;
|
|
54
|
+
}
|
|
55
|
+
set flipY(v) {
|
|
56
|
+
this.renderer.scaleY = v ? 1 : -1;
|
|
57
|
+
}
|
|
58
|
+
// ── Public methods ────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Set the global time scale for all animations on this skeleton.
|
|
61
|
+
*/
|
|
62
|
+
setTimeScale(scale) {
|
|
63
|
+
this.state.timeScale = scale;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Set the cross-fade mix time between two animations.
|
|
67
|
+
* Omit both names to set the default mix for all transitions.
|
|
68
|
+
*/
|
|
69
|
+
setMix(mixTime, fromAnim, toAnim) {
|
|
70
|
+
if (fromAnim && toAnim) {
|
|
71
|
+
this.stateData.setMix(fromAnim, toAnim, mixTime);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.stateData.defaultMix = mixTime;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Return all skin names defined in the skeleton data.
|
|
79
|
+
*/
|
|
80
|
+
getAllSkinNames() {
|
|
81
|
+
return this.skeletonData.skins.map(s => s.name);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Switch to the named skin and reset the skeleton to its setup pose.
|
|
85
|
+
*/
|
|
86
|
+
setSkinByName(name) {
|
|
87
|
+
this.skeleton.setSkinByName(name);
|
|
88
|
+
this.skeleton.setSlotsToSetupPose();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Play a single animation.
|
|
92
|
+
* @param anim Animation name.
|
|
93
|
+
* @param loop Number of times to play. 0 = loop forever.
|
|
94
|
+
* @param trackID Spine track index (default 0).
|
|
95
|
+
* @param listener Optional lifecycle callbacks.
|
|
96
|
+
*/
|
|
97
|
+
play(anim, loop = 0, trackID = 0, listener) {
|
|
98
|
+
return this.start(trackID).add(anim, loop, listener);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Play the first animation in the skeleton data, or a named one.
|
|
102
|
+
*/
|
|
103
|
+
playDefault(anim, loop = 0, trackID = 0, listener) {
|
|
104
|
+
const name = anim ?? this.skeletonData.animations[0].name;
|
|
105
|
+
return this.start(trackID).add(name, loop, listener);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Queue a list of animations on the given track.
|
|
109
|
+
*/
|
|
110
|
+
playList(animList, loop = 0, trackID = 0) {
|
|
111
|
+
const track = this.start(trackID);
|
|
112
|
+
for (const anim of animList) {
|
|
113
|
+
track.add(anim, loop);
|
|
114
|
+
}
|
|
115
|
+
return track;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Queue all animations defined in the skeleton data.
|
|
119
|
+
*/
|
|
120
|
+
playAll(loop = 0, trackID = 0) {
|
|
121
|
+
const track = this.start(trackID);
|
|
122
|
+
for (const anim of this.skeletonData.animations) {
|
|
123
|
+
track.add(anim.name, loop);
|
|
124
|
+
}
|
|
125
|
+
return track;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Play a randomly chosen animation.
|
|
129
|
+
*/
|
|
130
|
+
playRandom(trackID = 0) {
|
|
131
|
+
const names = this.skeletonData.animations.map(a => a.name);
|
|
132
|
+
const name = names[Math.floor(Math.random() * names.length)];
|
|
133
|
+
return this.start(trackID).add(name, 0);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Reset the skeleton to its setup pose and return a new Track for the given track ID.
|
|
137
|
+
*/
|
|
138
|
+
start(trackID = 0) {
|
|
139
|
+
this.skeleton.setToSetupPose();
|
|
140
|
+
return new Track(this, trackID);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Clear a single animation track.
|
|
144
|
+
*/
|
|
145
|
+
stop(trackID) {
|
|
146
|
+
this.state.clearTrack(trackID);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Clear all animation tracks.
|
|
150
|
+
* @param reset If true, also resets the skeleton to its setup pose.
|
|
151
|
+
*/
|
|
152
|
+
stopAll(reset) {
|
|
153
|
+
this.state.clearTracks();
|
|
154
|
+
if (reset)
|
|
155
|
+
this.skeleton.setToSetupPose();
|
|
156
|
+
}
|
|
157
|
+
// ── Override methods ──────────────────────────────────────────────────────
|
|
158
|
+
$onAddToStage(stage, $nestLevel) {
|
|
159
|
+
super.$onAddToStage(stage, $nestLevel);
|
|
160
|
+
this._lastTime = Date.now();
|
|
161
|
+
this.addEventListener(Event.ENTER_FRAME, this._handleEnterFrame);
|
|
162
|
+
}
|
|
163
|
+
$onRemoveFromStage() {
|
|
164
|
+
super.$onRemoveFromStage();
|
|
165
|
+
this.removeEventListener(Event.ENTER_FRAME, this._handleEnterFrame);
|
|
166
|
+
}
|
|
167
|
+
// ── Private methods ───────────────────────────────────────────────────────
|
|
168
|
+
_handleEnterFrame = (_e) => {
|
|
169
|
+
const now = Date.now();
|
|
170
|
+
this.renderer.update(now - this._lastTime);
|
|
171
|
+
this._lastTime = now;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Suppress unused import warning until implementation is complete
|
|
175
|
+
void Track;
|
|
176
|
+
//# sourceMappingURL=SkeletonAnimation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkeletonAnimation.js","sourceRoot":"","sources":["../../src/kurot/SkeletonAnimation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AnimationState, AnimationStateData, Skeleton, SkeletonClipping, SkeletonData } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { Sprite } from '@kurot/core';
|
|
3
|
+
import { SlotRenderer } from './SlotRenderer.js';
|
|
4
|
+
/**
|
|
5
|
+
* A Kurot `Sprite` container that holds one `SlotRenderer` (Mesh) per Spine slot.
|
|
6
|
+
* Drives the animation state and updates all slot meshes each frame.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SkeletonRenderer extends Sprite {
|
|
9
|
+
readonly skeleton: Skeleton;
|
|
10
|
+
readonly skeletonData: SkeletonData;
|
|
11
|
+
readonly state: AnimationState;
|
|
12
|
+
readonly stateData: AnimationStateData;
|
|
13
|
+
readonly slotRenderers: SlotRenderer[];
|
|
14
|
+
readonly clipper: SkeletonClipping;
|
|
15
|
+
constructor(skeletonData: SkeletonData);
|
|
16
|
+
/**
|
|
17
|
+
* Advance the animation state and update all slot meshes.
|
|
18
|
+
* @param dt Elapsed time in milliseconds.
|
|
19
|
+
*/
|
|
20
|
+
update(dt: number): void;
|
|
21
|
+
/**
|
|
22
|
+
* Find a `SlotRenderer` by slot name.
|
|
23
|
+
*/
|
|
24
|
+
findSlotRenderer(name: string): SlotRenderer | undefined;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=SkeletonRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkeletonRenderer.d.ts","sourceRoot":"","sources":["../../src/kurot/SkeletonRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,kBAAkB,EAElB,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,MAAM;IAG3C,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,YAAY,EAAE,YAAY,CAAC;IAC3C,SAAgB,KAAK,EAAE,cAAc,CAAC;IACtC,SAAgB,SAAS,EAAE,kBAAkB,CAAC;IAC9C,SAAgB,aAAa,EAAE,YAAY,EAAE,CAAM;IACnD,SAAgB,OAAO,EAAE,gBAAgB,CAA0B;gBAIhD,YAAY,EAAE,YAAY;IAyB7C;;;OAGG;IACI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAkB/B;;OAEG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAG/D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { AnimationState, AnimationStateData, Physics, Skeleton, SkeletonClipping, } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { Sprite } from '@kurot/core';
|
|
3
|
+
import { SlotRenderer } from './SlotRenderer.js';
|
|
4
|
+
/**
|
|
5
|
+
* A Kurot `Sprite` container that holds one `SlotRenderer` (Mesh) per Spine slot.
|
|
6
|
+
* Drives the animation state and updates all slot meshes each frame.
|
|
7
|
+
*/
|
|
8
|
+
export class SkeletonRenderer extends Sprite {
|
|
9
|
+
// ── Instance fields ───────────────────────────────────────────────────────
|
|
10
|
+
skeleton;
|
|
11
|
+
skeletonData;
|
|
12
|
+
state;
|
|
13
|
+
stateData;
|
|
14
|
+
slotRenderers = [];
|
|
15
|
+
clipper = new SkeletonClipping();
|
|
16
|
+
// ── Constructor ───────────────────────────────────────────────────────────
|
|
17
|
+
constructor(skeletonData) {
|
|
18
|
+
super();
|
|
19
|
+
this.skeletonData = skeletonData;
|
|
20
|
+
this.stateData = new AnimationStateData(skeletonData);
|
|
21
|
+
this.state = new AnimationState(this.stateData);
|
|
22
|
+
this.skeleton = new Skeleton(skeletonData);
|
|
23
|
+
// Spine Y-axis is inverted relative to screen coordinates
|
|
24
|
+
this.scaleY = -1;
|
|
25
|
+
// Draw order changes every frame — enable z-index sorting
|
|
26
|
+
this.sortableChildren = true;
|
|
27
|
+
this.skeleton.updateWorldTransform(Physics.update);
|
|
28
|
+
this.skeleton.setSlotsToSetupPose();
|
|
29
|
+
for (const slot of this.skeleton.slots) {
|
|
30
|
+
const renderer = new SlotRenderer(slot, this.clipper);
|
|
31
|
+
renderer.renderSlot();
|
|
32
|
+
this.addChild(renderer);
|
|
33
|
+
this.slotRenderers.push(renderer);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// ── Public methods ────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Advance the animation state and update all slot meshes.
|
|
39
|
+
* @param dt Elapsed time in milliseconds.
|
|
40
|
+
*/
|
|
41
|
+
update(dt) {
|
|
42
|
+
this.state.update(dt / 1000);
|
|
43
|
+
this.state.apply(this.skeleton);
|
|
44
|
+
this.skeleton.updateWorldTransform(Physics.update);
|
|
45
|
+
const drawOrder = this.skeleton.drawOrder;
|
|
46
|
+
for (let i = 0; i < drawOrder.length; i++) {
|
|
47
|
+
const slotIndex = drawOrder[i].data.index;
|
|
48
|
+
const renderer = this.slotRenderers[slotIndex];
|
|
49
|
+
if (renderer.zIndex !== i) {
|
|
50
|
+
renderer.zIndex = i;
|
|
51
|
+
}
|
|
52
|
+
renderer.renderSlot();
|
|
53
|
+
}
|
|
54
|
+
this.clipper.clipEnd();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Find a `SlotRenderer` by slot name.
|
|
58
|
+
*/
|
|
59
|
+
findSlotRenderer(name) {
|
|
60
|
+
return this.slotRenderers.find(r => r.name === name);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=SkeletonRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkeletonRenderer.js","sourceRoot":"","sources":["../../src/kurot/SkeletonRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,EACd,kBAAkB,EAClB,OAAO,EACP,QAAQ,EACR,gBAAgB,GAEhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM;IAC3C,6EAA6E;IAE7D,QAAQ,CAAW;IACnB,YAAY,CAAe;IAC3B,KAAK,CAAiB;IACtB,SAAS,CAAqB;IAC9B,aAAa,GAAmB,EAAE,CAAC;IACnC,OAAO,GAAqB,IAAI,gBAAgB,EAAE,CAAC;IAEnE,6EAA6E;IAE7E,YAAmB,YAA0B;QAC5C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,kBAAkB,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE3C,0DAA0D;QAC1D,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjB,0DAA0D;QAC1D,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACtD,QAAQ,CAAC,UAAU,EAAE,CAAC;YACtB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IAED,6EAA6E;IAE7E;;;OAGG;IACI,MAAM,CAAC,EAAU;QACvB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YACrB,CAAC;YACD,QAAQ,CAAC,UAAU,EAAE,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,IAAY;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACtD,CAAC;CACD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Slot, type SkeletonClipping } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { Mesh } from '@kurot/core';
|
|
3
|
+
/**
|
|
4
|
+
* A Kurot mesh that renders one Spine 4.2 slot.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SlotRenderer extends Mesh {
|
|
7
|
+
readonly slot: Slot;
|
|
8
|
+
readonly clipper: SkeletonClipping;
|
|
9
|
+
private readonly _finalColor;
|
|
10
|
+
private _worldVertices;
|
|
11
|
+
constructor(slot: Slot, clipper: SkeletonClipping);
|
|
12
|
+
/**
|
|
13
|
+
* Update mesh geometry from the current slot attachment.
|
|
14
|
+
*/
|
|
15
|
+
renderSlot(): void;
|
|
16
|
+
private _renderRegion;
|
|
17
|
+
private _renderMesh;
|
|
18
|
+
private _applyGeometry;
|
|
19
|
+
private _applyTexture;
|
|
20
|
+
private _updateColor;
|
|
21
|
+
private _ensureWorldVertices;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=SlotRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlotRenderer.d.ts","sourceRoot":"","sources":["../../src/kurot/SlotRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAMN,KAAK,IAAI,EACT,KAAK,gBAAgB,EAIrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAkC,MAAM,aAAa,CAAC;AAMnE;;GAEG;AACH,qBAAa,YAAa,SAAQ,IAAI;aASpB,IAAI,EAAE,IAAI;aACV,OAAO,EAAE,gBAAgB;IAP1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,cAAc,CAAqC;gBAK1C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,gBAAgB;IAS1C;;OAEG;IACI,UAAU,IAAI,IAAI;IA+BzB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,oBAAoB;CAG5B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { BlendMode as SpineBlendMode, ClippingAttachment, Color, MeshAttachment, RegionAttachment, } from '@esotericsoftware/spine-core';
|
|
2
|
+
import { Mesh, Texture, BlendMode } from '@kurot/core';
|
|
3
|
+
const QUAD_INDICES = [0, 1, 2, 2, 3, 0];
|
|
4
|
+
const DARK_COLOR = new Color(0, 0, 0, 0);
|
|
5
|
+
/**
|
|
6
|
+
* A Kurot mesh that renders one Spine 4.2 slot.
|
|
7
|
+
*/
|
|
8
|
+
export class SlotRenderer extends Mesh {
|
|
9
|
+
slot;
|
|
10
|
+
clipper;
|
|
11
|
+
// ── Instance fields ───────────────────────────────────────────────────────────────────────
|
|
12
|
+
_finalColor = new Color();
|
|
13
|
+
_worldVertices = new Float32Array(8);
|
|
14
|
+
// ── Constructor ────────────────────────────────────────────────────────────────────────
|
|
15
|
+
constructor(slot, clipper) {
|
|
16
|
+
super();
|
|
17
|
+
this.slot = slot;
|
|
18
|
+
this.clipper = clipper;
|
|
19
|
+
this.name = slot.data.name;
|
|
20
|
+
if (slot.data.blendMode === SpineBlendMode.Additive)
|
|
21
|
+
this.blendMode = BlendMode.ADD;
|
|
22
|
+
}
|
|
23
|
+
// ── Public methods ───────────────────────────────────────────────────────────────────
|
|
24
|
+
/**
|
|
25
|
+
* Update mesh geometry from the current slot attachment.
|
|
26
|
+
*/
|
|
27
|
+
renderSlot() {
|
|
28
|
+
const attachment = this.slot.getAttachment();
|
|
29
|
+
if (!this.slot.bone.active || !attachment) {
|
|
30
|
+
this.clipper.clipEndWithSlot(this.slot);
|
|
31
|
+
this.visible = false;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (attachment instanceof ClippingAttachment) {
|
|
35
|
+
this.clipper.clipStart(this.slot, attachment);
|
|
36
|
+
this.visible = false;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.visible = true;
|
|
40
|
+
if (attachment instanceof RegionAttachment) {
|
|
41
|
+
this._updateColor(attachment.color);
|
|
42
|
+
this._renderRegion(attachment);
|
|
43
|
+
}
|
|
44
|
+
else if (attachment instanceof MeshAttachment) {
|
|
45
|
+
this._updateColor(attachment.color);
|
|
46
|
+
this._renderMesh(attachment);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.visible = false;
|
|
50
|
+
}
|
|
51
|
+
this.clipper.clipEndWithSlot(this.slot);
|
|
52
|
+
if (this.visible)
|
|
53
|
+
this.updateVertices();
|
|
54
|
+
}
|
|
55
|
+
// ── Private methods ───────────────────────────────────────────────────────────────────
|
|
56
|
+
_renderRegion(attachment) {
|
|
57
|
+
this._ensureWorldVertices(8);
|
|
58
|
+
attachment.computeWorldVertices(this.slot, this._worldVertices, 0, 2);
|
|
59
|
+
this._applyGeometry(this._worldVertices, 8, QUAD_INDICES, attachment.uvs);
|
|
60
|
+
this._applyTexture(attachment.region);
|
|
61
|
+
}
|
|
62
|
+
_renderMesh(attachment) {
|
|
63
|
+
const count = attachment.worldVerticesLength;
|
|
64
|
+
this._ensureWorldVertices(count);
|
|
65
|
+
attachment.computeWorldVertices(this.slot, 0, count, this._worldVertices, 0, 2);
|
|
66
|
+
this._applyGeometry(this._worldVertices, count, attachment.triangles, attachment.uvs);
|
|
67
|
+
this._applyTexture(attachment.region);
|
|
68
|
+
}
|
|
69
|
+
_applyGeometry(vertices, vertexCount, triangles, uvs) {
|
|
70
|
+
if (!this.clipper.isClipping()) {
|
|
71
|
+
this.vertices = Array.from(vertices.subarray(0, vertexCount));
|
|
72
|
+
this.uvs = Array.from(uvs);
|
|
73
|
+
this.indices = triangles.slice();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.clipper.clipTriangles(vertices, vertexCount, triangles, triangles.length, uvs, this._finalColor, DARK_COLOR, false);
|
|
77
|
+
const packed = this.clipper.clippedVertices;
|
|
78
|
+
const clippedVertices = [];
|
|
79
|
+
const clippedUVs = [];
|
|
80
|
+
for (let i = 0; i < packed.length; i += 8) {
|
|
81
|
+
clippedVertices.push(packed[i], packed[i + 1]);
|
|
82
|
+
clippedUVs.push(packed[i + 6], packed[i + 7]);
|
|
83
|
+
}
|
|
84
|
+
this.vertices = clippedVertices;
|
|
85
|
+
this.uvs = clippedUVs;
|
|
86
|
+
this.indices = this.clipper.clippedTriangles.slice();
|
|
87
|
+
}
|
|
88
|
+
_applyTexture(region) {
|
|
89
|
+
const atlasRegion = region;
|
|
90
|
+
const kurotTexture = atlasRegion?.page?.texture;
|
|
91
|
+
if (!kurotTexture?.bitmapData)
|
|
92
|
+
return;
|
|
93
|
+
const bitmapData = kurotTexture.bitmapData;
|
|
94
|
+
if (!this.texture || this.texture.bitmapData !== bitmapData) {
|
|
95
|
+
const texture = new Texture();
|
|
96
|
+
texture.setBitmapData(bitmapData);
|
|
97
|
+
this.texture = texture;
|
|
98
|
+
this.smoothing = kurotTexture.smoothing;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
_updateColor(attachmentColor) {
|
|
102
|
+
const skeleton = this.slot.getSkeleton();
|
|
103
|
+
const color = this._finalColor;
|
|
104
|
+
color.r = skeleton.color.r * this.slot.color.r * attachmentColor.r;
|
|
105
|
+
color.g = skeleton.color.g * this.slot.color.g * attachmentColor.g;
|
|
106
|
+
color.b = skeleton.color.b * this.slot.color.b * attachmentColor.b;
|
|
107
|
+
color.a = skeleton.color.a * this.slot.color.a * attachmentColor.a;
|
|
108
|
+
this.tint = ((color.r * 255) << 16) | ((color.g * 255) << 8) | ((color.b * 255) | 0);
|
|
109
|
+
this.alpha = color.a;
|
|
110
|
+
}
|
|
111
|
+
_ensureWorldVertices(count) {
|
|
112
|
+
if (this._worldVertices.length < count)
|
|
113
|
+
this._worldVertices = new Float32Array(count);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=SlotRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlotRenderer.js","sourceRoot":"","sources":["../../src/kurot/SlotRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,SAAS,IAAI,cAAc,EAC3B,kBAAkB,EAClB,KAAK,EACL,cAAc,EACd,gBAAgB,GAMhB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAc,SAAS,EAAE,MAAM,aAAa,CAAC;AAGnE,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACxC,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,IAAI;IASpB;IACA;IATjB,6FAA6F;IAE5E,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;IACnC,cAAc,GAAiB,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IAE3D,0FAA0F;IAE1F,YACiB,IAAU,EACV,OAAyB;QAEzC,KAAK,EAAE,CAAC;QAHQ,SAAI,GAAJ,IAAI,CAAM;QACV,YAAO,GAAP,OAAO,CAAkB;QAGzC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,cAAc,CAAC,QAAQ;YAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC;IACrF,CAAC;IAED,wFAAwF;IAExF;;OAEG;IACI,UAAU;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,OAAO;QACR,CAAC;QAED,IAAI,UAAU,YAAY,kBAAkB,EAAE,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,OAAO;QACR,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,UAAU,YAAY,gBAAgB,EAAE,CAAC;YAC5C,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,UAAU,YAAY,cAAc,EAAE,CAAC;YACjD,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,cAAc,EAAE,CAAC;IACzC,CAAC;IAED,yFAAyF;IAEjF,aAAa,CAAC,UAA4B;QACjD,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC7B,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1E,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,WAAW,CAAC,UAA0B;QAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,mBAAmB,CAAC;QAC7C,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACjC,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QACtF,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,cAAc,CACrB,QAAsB,EACtB,WAAmB,EACnB,SAAmB,EACnB,GAAoB;QAEpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,aAAa,CACzB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,SAAS,CAAC,MAAM,EAChB,GAAG,EACH,IAAI,CAAC,WAAW,EAChB,UAAU,EACV,KAAK,CACL,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;QAC5C,MAAM,eAAe,GAAa,EAAE,CAAC;QACrC,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,eAAe,CAAC;QAChC,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACtD,CAAC;IAEO,aAAa,CAAC,MAA4B;QACjD,MAAM,WAAW,GAAG,MAAmC,CAAC;QACxD,MAAM,YAAY,GAAG,WAAW,EAAE,IAAI,EAAE,OAAmC,CAAC;QAC5E,IAAI,CAAC,YAAY,EAAE,UAAU;YAAE,OAAO;QACtC,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,IAAK,IAAI,CAAC,OAAmB,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YAC1E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;YAC9B,OAAO,CAAC,aAAa,CAAC,UAAwB,CAAC,CAAC;YAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC;QACzC,CAAC;IACF,CAAC;IAEO,YAAY,CAAC,eAAsB;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;QAC/B,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;QACnE,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;QACnE,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;QACnE,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;IACtB,CAAC;IAEO,oBAAoB,CAAC,KAAa;QACzC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,KAAK;YAAE,IAAI,CAAC,cAAc,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACvF,CAAC;CACD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { EventEmitter } from './EventEmitter.js';
|
|
2
|
+
type SkeletonAnimationRef = any;
|
|
3
|
+
/**
|
|
4
|
+
* Animation event types dispatched by a Track.
|
|
5
|
+
*/
|
|
6
|
+
export declare const enum SpineEvent {
|
|
7
|
+
PlayStart = 0,
|
|
8
|
+
PlayEnd = 1,
|
|
9
|
+
LoopStart = 2,
|
|
10
|
+
LoopEnd = 3,
|
|
11
|
+
Interrupt = 4,
|
|
12
|
+
Custom = 5,
|
|
13
|
+
TrackEnd = 6
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Per-animation lifecycle callbacks, passed to `Track.add()`.
|
|
17
|
+
*/
|
|
18
|
+
export interface AnimationListener {
|
|
19
|
+
playStart?: () => void;
|
|
20
|
+
playEnd?: () => void;
|
|
21
|
+
loopStart?: () => void;
|
|
22
|
+
loopEnd?: () => void;
|
|
23
|
+
interrupt?: () => void;
|
|
24
|
+
custom?: (event: unknown) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Manages a queue of animations on a single Spine track.
|
|
28
|
+
*
|
|
29
|
+
* Animations are played sequentially. Each entry can specify a loop count
|
|
30
|
+
* and lifecycle callbacks. Promise-based helpers allow `await`-ing events.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const track = hero.start(0);
|
|
35
|
+
* track.add('idle', 0); // loop forever
|
|
36
|
+
* track.add('attack', 1); // play once, then continue queue
|
|
37
|
+
* await track.waitPlayEnd();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class Track extends EventEmitter<SpineEvent> {
|
|
41
|
+
readonly trackID: number;
|
|
42
|
+
readonly skelAnimation: SkeletonAnimationRef;
|
|
43
|
+
trackEntry: unknown;
|
|
44
|
+
private _animations;
|
|
45
|
+
private _disposed;
|
|
46
|
+
private _loop;
|
|
47
|
+
private _stateListener;
|
|
48
|
+
constructor(skelAnimation: SkeletonAnimationRef, trackID: number);
|
|
49
|
+
/**
|
|
50
|
+
* Add an animation to the queue.
|
|
51
|
+
* @param name Animation name as defined in the Spine editor.
|
|
52
|
+
* @param loop Number of times to play. 0 = loop forever.
|
|
53
|
+
* @param listener Optional lifecycle callbacks for this animation.
|
|
54
|
+
*/
|
|
55
|
+
add(name: string, loop?: number, listener?: AnimationListener): this;
|
|
56
|
+
/**
|
|
57
|
+
* Jump the track entry to its last frame.
|
|
58
|
+
*/
|
|
59
|
+
setToLastFrame(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Resolves when the current animation's first loop begins.
|
|
62
|
+
*/
|
|
63
|
+
waitPlayStart(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Resolves when the current animation finishes all its loops.
|
|
66
|
+
*/
|
|
67
|
+
waitPlayEnd(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Resolves at the start of each loop iteration.
|
|
70
|
+
*/
|
|
71
|
+
waitLoopStart(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Resolves at the end of each loop iteration.
|
|
74
|
+
*/
|
|
75
|
+
waitLoopEnd(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Resolves when the track is interrupted by another animation.
|
|
78
|
+
*/
|
|
79
|
+
waitInterrupt(): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Resolves when the entire animation queue is exhausted.
|
|
82
|
+
*/
|
|
83
|
+
waitTrackEnd(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Resolves on the next Spine frame event.
|
|
86
|
+
*/
|
|
87
|
+
waitEvent(): Promise<unknown>;
|
|
88
|
+
/**
|
|
89
|
+
* Resolves when a Spine frame event with the given name fires.
|
|
90
|
+
*/
|
|
91
|
+
waitNamedEvent(name: string): Promise<unknown>;
|
|
92
|
+
private _playNext;
|
|
93
|
+
private _setAnimation;
|
|
94
|
+
private _onComplete;
|
|
95
|
+
private _onInterrupt;
|
|
96
|
+
private _onCustomEvent;
|
|
97
|
+
}
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=Track.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Track.d.ts","sourceRoot":"","sources":["../../src/kurot/Track.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,KAAK,oBAAoB,GAAG,GAAG,CAAC;AAEhC;;GAEG;AACH,0BAAkB,UAAU;IAC3B,SAAS,IAAA;IACT,OAAO,IAAA;IACP,SAAS,IAAA;IACT,OAAO,IAAA;IACP,SAAS,IAAA;IACT,MAAM,IAAA;IACN,QAAQ,IAAA;CACR;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAQD;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,SAAQ,YAAY,CAAC,UAAU,CAAC;IAGlD,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,SAAgB,aAAa,EAAE,oBAAoB,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC;IAE3B,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,cAAc,CAAU;gBAIb,aAAa,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;IAgBvE;;;;;OAKG;IACI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAI,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI;IAUtE;;OAEG;IACI,cAAc,IAAI,IAAI;IAS7B;;OAEG;IACI,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;OAEG;IACI,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;OAEG;IACI,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;OAEG;IACI,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;OAEG;IACI,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;OAEG;IACI,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;OAEG;IACI,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAIpC;;OAEG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAerD,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;CAKtB"}
|