@eva/plugin-renderer-sprite-animation 2.1.0-beta.1 → 2.1.0-beta.10

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.
@@ -41,6 +41,10 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
41
41
  step((generator = generator.apply(thisArg, _arguments || [])).next());
42
42
  });
43
43
  }
44
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
45
+ var e = new Error(message);
46
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
47
+ };
44
48
  function __rest(s, e) {
45
49
  var t = {};
46
50
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
@@ -160,6 +164,7 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
160
164
  this.times = Infinity;
161
165
  this.count = 0;
162
166
  this.complete = false;
167
+ this.activeClipLoop = false;
163
168
  this.listenerBound = false;
164
169
  this.init(params);
165
170
  }
@@ -169,14 +174,23 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
169
174
  this.listenerBound = true;
170
175
  this.on('loop', () => {
171
176
  var _a;
177
+ if (this.complete) return;
178
+ if (this.activeClip) {
179
+ if (this.activeClipLoop) {
180
+ this.animate.gotoAndPlay(this.activeClip.start);
181
+ } else {
182
+ this.animate.gotoAndStop(this.activeClip.end);
183
+ this.finish();
184
+ }
185
+ return;
186
+ }
172
187
  if (++this.count >= this.times) {
173
188
  if (this.forwards) {
174
189
  this.gotoAndStop(this.totalFrames - 1);
175
190
  } else {
176
191
  (_a = this.animate) === null || _a === void 0 ? void 0 : _a.stop();
177
192
  }
178
- this.complete = true;
179
- this.emit('complete');
193
+ this.finish();
180
194
  }
181
195
  });
182
196
  this.on('complete', () => {
@@ -185,20 +199,53 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
185
199
  });
186
200
  this.on('frameChange', () => {
187
201
  var _a;
188
- (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, this.currentFrame);
202
+ const frame = this.currentFrame;
203
+ (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, frame);
204
+ if (!this.complete && this.activeClip && frame >= this.activeClip.end) {
205
+ if (this.activeClipLoop) {
206
+ this.animate.gotoAndPlay(this.activeClip.start);
207
+ } else {
208
+ this.animate.stop();
209
+ if (frame > this.activeClip.end) {
210
+ this.animate.gotoAndStop(this.activeClip.end);
211
+ }
212
+ this.finish();
213
+ }
214
+ }
189
215
  });
190
216
  }
191
217
  }
218
+ finish() {
219
+ if (this.complete) return;
220
+ this.complete = true;
221
+ this.emit('complete');
222
+ }
223
+ _handleRendererComplete() {
224
+ this.finish();
225
+ }
226
+ isValidClip(clip) {
227
+ return Number.isInteger(clip.start) && Number.isInteger(clip.end) && clip.start >= 0 && clip.start <= clip.end && clip.end < this.totalFrames;
228
+ }
192
229
  play(nameOrTimes = Infinity, loop = false) {
193
- let times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
230
+ const times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
194
231
  let startFrame;
195
232
  if (typeof nameOrTimes === 'string') {
196
233
  this.currentAnimation = nameOrTimes;
234
+ this.activeClip = undefined;
235
+ this.activeClipLoop = false;
197
236
  const clip = this.animations[nameOrTimes];
198
237
  if (clip) {
199
238
  startFrame = clip.start;
239
+ if (this.animate && this.isValidClip(clip)) {
240
+ this.activeClip = clip;
241
+ this.activeClipLoop = loop;
242
+ }
200
243
  if (clip.speed !== undefined) this.speed = clip.speed;
201
244
  }
245
+ } else {
246
+ this.currentAnimation = undefined;
247
+ this.activeClip = undefined;
248
+ this.activeClipLoop = false;
202
249
  }
203
250
  if (times === 0) {
204
251
  return;
@@ -209,16 +256,16 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
209
256
  this.waitAnimation = typeof nameOrTimes === 'string' ? nameOrTimes : undefined;
210
257
  this.waitLoop = loop;
211
258
  } else {
212
- if (this.complete) {
259
+ if (this.complete && startFrame === undefined) {
213
260
  this.gotoAndStop(0);
214
261
  }
262
+ this.count = 0;
263
+ this.complete = false;
215
264
  if (startFrame !== undefined) {
216
265
  this.animate.gotoAndPlay(startFrame);
217
266
  } else {
218
267
  this.animate.play();
219
268
  }
220
- this.count = 0;
221
- this.complete = false;
222
269
  }
223
270
  }
224
271
  stop() {
@@ -400,7 +447,7 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
400
447
  this.animates[id] = animate;
401
448
  this.containerManager.getContainer(id).addChildAt(animate.animatedSprite, 0);
402
449
  animate.animatedSprite.onComplete = () => {
403
- component.emit('complete');
450
+ component._handleRendererComplete();
404
451
  };
405
452
  animate.animatedSprite.onFrameChange = () => {
406
453
  component.emit('frameChange');
@@ -1 +1 @@
1
- function _extends(){return _extends=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)({}).hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{};var _EVA_IIFE_spriteAnimation=function(t,e,n,i,o){"use strict";function r(t,e,n,i){var o,r=arguments.length,s=r<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,i);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(s=(r<3?o(s):r>3?o(e,n,s):o(e,n))||s);return r>3&&s&&Object.defineProperty(e,n,s),s}function s(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}function a(t,e,n,i){return new(n||(n=Promise))(function(o,r){function s(t){try{c(i.next(t))}catch(t){r(t)}}function a(t){try{c(i.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n(function(t){t(e)})).then(s,a)}c((i=i.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class c extends Error{constructor(){super("Symbol keys are not supported yet!"),Object.setPrototypeOf(this,new.target.prototype)}}const p="IDE_PROPERTY_METADATA";function m(t,e,n,i){let o=Reflect.getMetadata("design:type",t,e),r=o===Array;const s=function(t){return t===String?"string":t===Number?"number":t===Boolean?"boolean":"unknown"}(o);if("unknown"!==s&&(o=s),i){const t=i();Array.isArray(t)?(r=!0,o=t[0]):o=t}const a=Reflect.getMetadata(p,t.constructor)||{},c=_extends(_extends(_extends({},a[e]||{}),{type:o,isArray:r}),n);a[e]=c,Reflect.defineMetadata(p,a,t.constructor);!function(t,e,n){const i=t.constructor,o=i.IDEProps||{};o[e]=_extends(_extends({key:e},o[e]),n),i.IDEProps=o}(t,e,function(t,e){var n={};for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(n[i]=t[i]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(t);o<i.length;o++)e.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(t,i[o])&&(n[i[o]]=t[i[o]])}return n}(c,["isArray"]))}function d(t){return l({type:t})}function l(t,e){return(n,i)=>{if("symbol"==typeof i)throw new c;const{options:o,returnTypeFunc:r}=function(t,e){return"function"==typeof t?{returnTypeFunc:t,options:e||{}}:{options:t||{}}}(t,e);m(n,i,o,r)}}var h;!function(t){t[t.Edit=2]="Edit",t[t.Game=4]="Game",t[t.All=6]="All"}(h||(h={}));class u extends e.Component{constructor(t){super(t),this.resource="",this.autoPlay=!0,this.speed=100,this.forwards=!1,this.animations={},this.waitPlay=!1,this.waitLoop=!1,this.waitStop=!1,this.times=1/0,this.count=0,this.complete=!1,this.listenerBound=!1,this.init(t)}init(t){t&&_extends(this,t),this.listenerBound||(this.listenerBound=!0,this.on("loop",()=>{var t;++this.count>=this.times&&(this.forwards?this.gotoAndStop(this.totalFrames-1):null===(t=this.animate)||void 0===t||t.stop(),this.complete=!0,this.emit("complete"))}),this.on("complete",()=>{var t;null===(t=this.onComplete)||void 0===t||t.call(this)}),this.on("frameChange",()=>{var t;null===(t=this.onFrameChange)||void 0===t||t.call(this,this.currentFrame)}))}play(t=1/0,e=!1){let n,i="number"==typeof t?t:e?1/0:1;if("string"==typeof t){this.currentAnimation=t;const e=this.animations[t];e&&(n=e.start,void 0!==e.speed&&(this.speed=e.speed))}0!==i&&(this.times=i,this.animate?(this.complete&&this.gotoAndStop(0),void 0!==n?this.animate.gotoAndPlay(n):this.animate.play(),this.count=0,this.complete=!1):(this.waitPlay=!0,this.waitAnimation="string"==typeof t?t:void 0,this.waitLoop=e))}stop(){this.animate?this.animate.stop():this.waitStop=!0}set animate(t){if(this._animate=t,this.waitPlay){this.waitPlay=!1;const t=this.waitAnimation;this.waitAnimation=void 0,this.play(null!=t?t:this.times,this.waitLoop)}this.waitStop&&(this.waitStop=!1,this.stop())}get animate(){return this._animate}gotoAndPlay(t){this.animate.gotoAndPlay(t)}gotoAndStop(t){this.animate.gotoAndStop(t)}get currentFrame(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.currentFrame}get totalFrames(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.totalFrames}}u.componentName="SpriteAnimation",r([d("string"),s("design:type",String)],u.prototype,"resource",void 0),r([d("boolean"),s("design:type",Boolean)],u.prototype,"autoPlay",void 0),r([d("number"),function(t){return l({step:t})}(10),s("design:type",Number)],u.prototype,"speed",void 0),r([d("boolean"),s("design:type",Boolean)],u.prototype,"forwards",void 0);const f="_s|r|c_";e.resource.registerInstance(e.RESOURCE_TYPE.SPRITE_ANIMATION,({name:t,data:e})=>new Promise(n=>{var i;const r=e.json.data,s=e.image instanceof o.Texture?e.image:o.Texture.from(e.image);let a=r.frames||{};if(Array.isArray(a)){const t={};for(const e of a){const n=null!==(i=e.filename)&&void 0!==i?i:e.name;n&&(t[n]=e)}a=t}const c=r.animations||{},p={},m={};for(const e in a){m[t+f+e]=a[e]}for(const e in c){const n=[];if(c[e]&&c[e].length>=0)for(const i of c[e]){const e=t+f+i;n.push(e)}p[e]=n}const d=new o.Spritesheet(s,_extends(_extends({},r),{frames:m,animations:p}));d.parse().then(()=>{const{textures:t}=d,e=[];for(const n in t)e.push(t[n]);n(e)})})),e.resource.registerDestroy(e.RESOURCE_TYPE.SPRITE_ANIMATION,({instance:t})=>{if(t)for(const e of t)e.destroy(!0)});let y=class extends n.Renderer{constructor(){super(...arguments),this.name="SpriteAnimationSystem",this.animates={},this.autoPlay={}}init(){this.renderSystem=this.game.getSystem(n.RendererSystem),this.renderSystem.rendererManager.register(this)}rendererUpdate(t){const{width:e,height:n}=t.transform.size;this.animates[t.id]&&(this.animates[t.id].animatedSprite.width=e,this.animates[t.id].animatedSprite.height=n)}componentChanged(t){return a(this,void 0,void 0,function*(){const n=t.gameObject.id;if("SpriteAnimation"===t.componentName){const i=t.component;if(this.autoPlay[t.gameObject.id]=i.autoPlay,t.type===e.OBSERVER_TYPE.ADD){const o=this.increaseAsyncId(n),{instance:r}=yield e.resource.getResource(i.resource);if(!this.validateAsyncId(n,o))return;r||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.add({frames:r,id:t.gameObject.id,component:i})}else if(t.type===e.OBSERVER_TYPE.CHANGE)if(t.prop&&"speed"===t.prop.prop[0])this.animates[t.gameObject.id].speed=1e3/60/i.speed;else{const o=this.increaseAsyncId(n),{instance:r}=yield e.resource.getResource(i.resource);if(!this.validateAsyncId(n,o))return;r||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.change({frames:r,id:t.gameObject.id,component:i})}else t.type===e.OBSERVER_TYPE.REMOVE&&(this.increaseAsyncId(n),this.remove(t.gameObject.id))}})}add({frames:t,id:e,component:n}){const o=new i.SpriteAnimation({frames:t});this.animates[e]=o,this.containerManager.getContainer(e).addChildAt(o.animatedSprite,0),o.animatedSprite.onComplete=()=>{n.emit("complete")},o.animatedSprite.onFrameChange=()=>{n.emit("frameChange")},o.animatedSprite.onLoop=()=>{n.emit("loop")},n.animate=this.animates[e],this.animates[e].speed=1e3/60/n.speed,this.autoPlay[e]&&o.animatedSprite.play()}change({frames:t,id:e,component:n}){this.remove(e,!0),this.add({frames:t,id:e,component:n})}remove(t,e){const n=this.animates[t];n&&(this.autoPlay[t]=n.animatedSprite.playing,this.containerManager.getContainer(t).removeChild(n.animatedSprite),n.animatedSprite.destroy(),delete this.animates[t],e||delete this.autoPlay[t])}};y.systemName="SpriteAnimationSystem",y=r([e.decorators.componentObserver({SpriteAnimation:["speed","resource"]})],y);var g=y;return t.SpriteAnimation=u,t.SpriteAnimationSystem=g,Object.defineProperty(t,"__esModule",{value:!0}),t}({},EVA,EVA.plugin.renderer,EVA.rendererAdapter,PIXI);globalThis.EVA.plugin.renderer.spriteAnimation=globalThis.EVA.plugin.renderer.spriteAnimation||_EVA_IIFE_spriteAnimation;
1
+ function _extends(){return _extends=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var n in i)({}).hasOwnProperty.call(i,n)&&(t[n]=i[n])}return t},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{};var _EVA_IIFE_spriteAnimation=function(t,e,i,n,o){"use strict";function s(t,e,i,n){var o,s=arguments.length,a=s<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,i,n);else for(var r=t.length-1;r>=0;r--)(o=t[r])&&(a=(s<3?o(a):s>3?o(e,i,a):o(e,i))||a);return s>3&&a&&Object.defineProperty(e,i,a),a}function a(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}function r(t,e,i,n){return new(i||(i=Promise))(function(o,s){function a(t){try{p(n.next(t))}catch(t){s(t)}}function r(t){try{p(n.throw(t))}catch(t){s(t)}}function p(t){var e;t.done?o(t.value):(e=t.value,e instanceof i?e:new i(function(t){t(e)})).then(a,r)}p((n=n.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError,"function"==typeof SuppressedError&&SuppressedError;class p extends Error{constructor(){super("Symbol keys are not supported yet!"),Object.setPrototypeOf(this,new.target.prototype)}}const c="IDE_PROPERTY_METADATA";function l(t,e,i,n){let o=Reflect.getMetadata("design:type",t,e),s=o===Array;const a=function(t){return t===String?"string":t===Number?"number":t===Boolean?"boolean":"unknown"}(o);if("unknown"!==a&&(o=a),n){const t=n();Array.isArray(t)?(s=!0,o=t[0]):o=t}const r=Reflect.getMetadata(c,t.constructor)||{},p=_extends(_extends(_extends({},r[e]||{}),{type:o,isArray:s}),i);r[e]=p,Reflect.defineMetadata(c,r,t.constructor);!function(t,e,i){const n=t.constructor,o=n.IDEProps||{};o[e]=_extends(_extends({key:e},o[e]),i),n.IDEProps=o}(t,e,function(t,e){var i={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&e.indexOf(n)<0&&(i[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(t);o<n.length;o++)e.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(t,n[o])&&(i[n[o]]=t[n[o]])}return i}(p,["isArray"]))}function d(t){return h({type:t})}function h(t,e){return(i,n)=>{if("symbol"==typeof n)throw new p;const{options:o,returnTypeFunc:s}=function(t,e){return"function"==typeof t?{returnTypeFunc:t,options:e||{}}:{options:t||{}}}(t,e);l(i,n,o,s)}}var m;!function(t){t[t.Edit=2]="Edit",t[t.Game=4]="Game",t[t.All=6]="All"}(m||(m={}));class u extends e.Component{constructor(t){super(t),this.resource="",this.autoPlay=!0,this.speed=100,this.forwards=!1,this.animations={},this.waitPlay=!1,this.waitLoop=!1,this.waitStop=!1,this.times=1/0,this.count=0,this.complete=!1,this.activeClipLoop=!1,this.listenerBound=!1,this.init(t)}init(t){t&&_extends(this,t),this.listenerBound||(this.listenerBound=!0,this.on("loop",()=>{var t;this.complete||(this.activeClip?this.activeClipLoop?this.animate.gotoAndPlay(this.activeClip.start):(this.animate.gotoAndStop(this.activeClip.end),this.finish()):++this.count>=this.times&&(this.forwards?this.gotoAndStop(this.totalFrames-1):null===(t=this.animate)||void 0===t||t.stop(),this.finish()))}),this.on("complete",()=>{var t;null===(t=this.onComplete)||void 0===t||t.call(this)}),this.on("frameChange",()=>{var t;const e=this.currentFrame;null===(t=this.onFrameChange)||void 0===t||t.call(this,e),!this.complete&&this.activeClip&&e>=this.activeClip.end&&(this.activeClipLoop?this.animate.gotoAndPlay(this.activeClip.start):(this.animate.stop(),e>this.activeClip.end&&this.animate.gotoAndStop(this.activeClip.end),this.finish()))}))}finish(){this.complete||(this.complete=!0,this.emit("complete"))}_handleRendererComplete(){this.finish()}isValidClip(t){return Number.isInteger(t.start)&&Number.isInteger(t.end)&&t.start>=0&&t.start<=t.end&&t.end<this.totalFrames}play(t=1/0,e=!1){const i="number"==typeof t?t:e?1/0:1;let n;if("string"==typeof t){this.currentAnimation=t,this.activeClip=void 0,this.activeClipLoop=!1;const i=this.animations[t];i&&(n=i.start,this.animate&&this.isValidClip(i)&&(this.activeClip=i,this.activeClipLoop=e),void 0!==i.speed&&(this.speed=i.speed))}else this.currentAnimation=void 0,this.activeClip=void 0,this.activeClipLoop=!1;0!==i&&(this.times=i,this.animate?(this.complete&&void 0===n&&this.gotoAndStop(0),this.count=0,this.complete=!1,void 0!==n?this.animate.gotoAndPlay(n):this.animate.play()):(this.waitPlay=!0,this.waitAnimation="string"==typeof t?t:void 0,this.waitLoop=e))}stop(){this.animate?this.animate.stop():this.waitStop=!0}set animate(t){if(this._animate=t,this.waitPlay){this.waitPlay=!1;const t=this.waitAnimation;this.waitAnimation=void 0,this.play(null!=t?t:this.times,this.waitLoop)}this.waitStop&&(this.waitStop=!1,this.stop())}get animate(){return this._animate}gotoAndPlay(t){this.animate.gotoAndPlay(t)}gotoAndStop(t){this.animate.gotoAndStop(t)}get currentFrame(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.currentFrame}get totalFrames(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.totalFrames}}u.componentName="SpriteAnimation",s([d("string"),a("design:type",String)],u.prototype,"resource",void 0),s([d("boolean"),a("design:type",Boolean)],u.prototype,"autoPlay",void 0),s([d("number"),function(t){return h({step:t})}(10),a("design:type",Number)],u.prototype,"speed",void 0),s([d("boolean"),a("design:type",Boolean)],u.prototype,"forwards",void 0);const f="_s|r|c_";e.resource.registerInstance(e.RESOURCE_TYPE.SPRITE_ANIMATION,({name:t,data:e})=>new Promise(i=>{var n;const s=e.json.data,a=e.image instanceof o.Texture?e.image:o.Texture.from(e.image);let r=s.frames||{};if(Array.isArray(r)){const t={};for(const e of r){const i=null!==(n=e.filename)&&void 0!==n?n:e.name;i&&(t[i]=e)}r=t}const p=s.animations||{},c={},l={};for(const e in r){l[t+f+e]=r[e]}for(const e in p){const i=[];if(p[e]&&p[e].length>=0)for(const n of p[e]){const e=t+f+n;i.push(e)}c[e]=i}const d=new o.Spritesheet(a,_extends(_extends({},s),{frames:l,animations:c}));d.parse().then(()=>{const{textures:t}=d,e=[];for(const i in t)e.push(t[i]);i(e)})})),e.resource.registerDestroy(e.RESOURCE_TYPE.SPRITE_ANIMATION,({instance:t})=>{if(t)for(const e of t)e.destroy(!0)});let y=class extends i.Renderer{constructor(){super(...arguments),this.name="SpriteAnimationSystem",this.animates={},this.autoPlay={}}init(){this.renderSystem=this.game.getSystem(i.RendererSystem),this.renderSystem.rendererManager.register(this)}rendererUpdate(t){const{width:e,height:i}=t.transform.size;this.animates[t.id]&&(this.animates[t.id].animatedSprite.width=e,this.animates[t.id].animatedSprite.height=i)}componentChanged(t){return r(this,void 0,void 0,function*(){const i=t.gameObject.id;if("SpriteAnimation"===t.componentName){const n=t.component;if(this.autoPlay[t.gameObject.id]=n.autoPlay,t.type===e.OBSERVER_TYPE.ADD){const o=this.increaseAsyncId(i),{instance:s}=yield e.resource.getResource(n.resource);if(!this.validateAsyncId(i,o))return;s||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.add({frames:s,id:t.gameObject.id,component:n})}else if(t.type===e.OBSERVER_TYPE.CHANGE)if(t.prop&&"speed"===t.prop.prop[0])this.animates[t.gameObject.id].speed=1e3/60/n.speed;else{const o=this.increaseAsyncId(i),{instance:s}=yield e.resource.getResource(n.resource);if(!this.validateAsyncId(i,o))return;s||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.change({frames:s,id:t.gameObject.id,component:n})}else t.type===e.OBSERVER_TYPE.REMOVE&&(this.increaseAsyncId(i),this.remove(t.gameObject.id))}})}add({frames:t,id:e,component:i}){const o=new n.SpriteAnimation({frames:t});this.animates[e]=o,this.containerManager.getContainer(e).addChildAt(o.animatedSprite,0),o.animatedSprite.onComplete=()=>{i._handleRendererComplete()},o.animatedSprite.onFrameChange=()=>{i.emit("frameChange")},o.animatedSprite.onLoop=()=>{i.emit("loop")},i.animate=this.animates[e],this.animates[e].speed=1e3/60/i.speed,this.autoPlay[e]&&o.animatedSprite.play()}change({frames:t,id:e,component:i}){this.remove(e,!0),this.add({frames:t,id:e,component:i})}remove(t,e){const i=this.animates[t];i&&(this.autoPlay[t]=i.animatedSprite.playing,this.containerManager.getContainer(t).removeChild(i.animatedSprite),i.animatedSprite.destroy(),delete this.animates[t],e||delete this.autoPlay[t])}};y.systemName="SpriteAnimationSystem",y=s([e.decorators.componentObserver({SpriteAnimation:["speed","resource"]})],y);var g=y;return t.SpriteAnimation=u,t.SpriteAnimationSystem=g,Object.defineProperty(t,"__esModule",{value:!0}),t}({},EVA,EVA.plugin.renderer,EVA.rendererAdapter,PIXI);globalThis.EVA.plugin.renderer.spriteAnimation=globalThis.EVA.plugin.renderer.spriteAnimation||_EVA_IIFE_spriteAnimation;
@@ -111,6 +111,8 @@ class SpriteAnimation$2 extends eva_js.Component {
111
111
  this.count = 0;
112
112
  /** 是否播放完成 */
113
113
  this.complete = false;
114
+ /** 当前命名动画是否循环 */
115
+ this.activeClipLoop = false;
114
116
  this.listenerBound = false;
115
117
  this.init(params);
116
118
  }
@@ -128,6 +130,18 @@ class SpriteAnimation$2 extends eva_js.Component {
128
130
  this.listenerBound = true;
129
131
  this.on('loop', () => {
130
132
  var _a;
133
+ if (this.complete)
134
+ return;
135
+ if (this.activeClip) {
136
+ if (this.activeClipLoop) {
137
+ this.animate.gotoAndPlay(this.activeClip.start);
138
+ }
139
+ else {
140
+ this.animate.gotoAndStop(this.activeClip.end);
141
+ this.finish();
142
+ }
143
+ return;
144
+ }
131
145
  if (++this.count >= this.times) {
132
146
  if (this.forwards) {
133
147
  this.gotoAndStop(this.totalFrames - 1);
@@ -135,8 +149,7 @@ class SpriteAnimation$2 extends eva_js.Component {
135
149
  else {
136
150
  (_a = this.animate) === null || _a === void 0 ? void 0 : _a.stop();
137
151
  }
138
- this.complete = true;
139
- this.emit('complete');
152
+ this.finish();
140
153
  }
141
154
  });
142
155
  this.on('complete', () => {
@@ -145,22 +158,64 @@ class SpriteAnimation$2 extends eva_js.Component {
145
158
  });
146
159
  this.on('frameChange', () => {
147
160
  var _a;
148
- (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, this.currentFrame);
161
+ const frame = this.currentFrame;
162
+ (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, frame);
163
+ if (!this.complete && this.activeClip && frame >= this.activeClip.end) {
164
+ if (this.activeClipLoop) {
165
+ this.animate.gotoAndPlay(this.activeClip.start);
166
+ }
167
+ else {
168
+ this.animate.stop();
169
+ if (frame > this.activeClip.end) {
170
+ this.animate.gotoAndStop(this.activeClip.end);
171
+ }
172
+ this.finish();
173
+ }
174
+ }
149
175
  });
150
176
  }
151
177
  }
178
+ finish() {
179
+ if (this.complete)
180
+ return;
181
+ this.complete = true;
182
+ this.emit('complete');
183
+ }
184
+ /** @internal Renderer event entry point; keeps late renderer callbacks idempotent. */
185
+ _handleRendererComplete() {
186
+ this.finish();
187
+ }
188
+ isValidClip(clip) {
189
+ return (Number.isInteger(clip.start) &&
190
+ Number.isInteger(clip.end) &&
191
+ clip.start >= 0 &&
192
+ clip.start <= clip.end &&
193
+ clip.end < this.totalFrames);
194
+ }
152
195
  play(nameOrTimes = Infinity, loop = false) {
153
- let times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
196
+ const times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
154
197
  let startFrame;
155
198
  if (typeof nameOrTimes === 'string') {
156
199
  this.currentAnimation = nameOrTimes;
200
+ this.activeClip = undefined;
201
+ this.activeClipLoop = false;
157
202
  const clip = this.animations[nameOrTimes];
158
203
  if (clip) {
159
204
  startFrame = clip.start;
205
+ // Invalid ranges keep the legacy start-only/full-timeline behavior instead of throwing.
206
+ if (this.animate && this.isValidClip(clip)) {
207
+ this.activeClip = clip;
208
+ this.activeClipLoop = loop;
209
+ }
160
210
  if (clip.speed !== undefined)
161
211
  this.speed = clip.speed;
162
212
  }
163
213
  }
214
+ else {
215
+ this.currentAnimation = undefined;
216
+ this.activeClip = undefined;
217
+ this.activeClipLoop = false;
218
+ }
164
219
  if (times === 0) {
165
220
  return;
166
221
  }
@@ -171,17 +226,17 @@ class SpriteAnimation$2 extends eva_js.Component {
171
226
  this.waitLoop = loop;
172
227
  }
173
228
  else {
174
- if (this.complete) {
229
+ if (this.complete && startFrame === undefined) {
175
230
  this.gotoAndStop(0);
176
231
  }
232
+ this.count = 0;
233
+ this.complete = false;
177
234
  if (startFrame !== undefined) {
178
235
  this.animate.gotoAndPlay(startFrame);
179
236
  }
180
237
  else {
181
238
  this.animate.play();
182
239
  }
183
- this.count = 0;
184
- this.complete = false;
185
240
  }
186
241
  }
187
242
  stop() {
@@ -364,7 +419,7 @@ let SpriteAnimation = class SpriteAnimation extends pluginRenderer.Renderer {
364
419
  this.animates[id] = animate;
365
420
  this.containerManager.getContainer(id).addChildAt(animate.animatedSprite, 0);
366
421
  animate.animatedSprite.onComplete = () => {
367
- component.emit('complete');
422
+ component._handleRendererComplete();
368
423
  };
369
424
  animate.animatedSprite.onFrameChange = () => {
370
425
  component.emit('frameChange');
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@eva/eva.js"),t=require("@eva/inspector-decorator"),i=require("@eva/plugin-renderer"),n=require("@eva/renderer-adapter"),s=require("pixi.js");function a(e,t,i,n){var s,a=arguments.length,o=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,n);else for(var r=e.length-1;r>=0;r--)(s=e[r])&&(o=(a<3?s(o):a>3?s(t,i,o):s(t,i))||o);return a>3&&o&&Object.defineProperty(t,i,o),o}function o(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function r(e,t,i,n){return new(i||(i=Promise))(function(s,a){function o(e){try{m(n.next(e))}catch(e){a(e)}}function r(e){try{m(n.throw(e))}catch(e){a(e)}}function m(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i(function(e){e(t)})).then(o,r)}m((n=n.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class m extends e.Component{constructor(e){super(e),this.resource="",this.autoPlay=!0,this.speed=100,this.forwards=!1,this.animations={},this.waitPlay=!1,this.waitLoop=!1,this.waitStop=!1,this.times=1/0,this.count=0,this.complete=!1,this.listenerBound=!1,this.init(e)}init(e){e&&Object.assign(this,e),this.listenerBound||(this.listenerBound=!0,this.on("loop",()=>{var e;++this.count>=this.times&&(this.forwards?this.gotoAndStop(this.totalFrames-1):null===(e=this.animate)||void 0===e||e.stop(),this.complete=!0,this.emit("complete"))}),this.on("complete",()=>{var e;null===(e=this.onComplete)||void 0===e||e.call(this)}),this.on("frameChange",()=>{var e;null===(e=this.onFrameChange)||void 0===e||e.call(this,this.currentFrame)}))}play(e=1/0,t=!1){let i,n="number"==typeof e?e:t?1/0:1;if("string"==typeof e){this.currentAnimation=e;const t=this.animations[e];t&&(i=t.start,void 0!==t.speed&&(this.speed=t.speed))}0!==n&&(this.times=n,this.animate?(this.complete&&this.gotoAndStop(0),void 0!==i?this.animate.gotoAndPlay(i):this.animate.play(),this.count=0,this.complete=!1):(this.waitPlay=!0,this.waitAnimation="string"==typeof e?e:void 0,this.waitLoop=t))}stop(){this.animate?this.animate.stop():this.waitStop=!0}set animate(e){if(this._animate=e,this.waitPlay){this.waitPlay=!1;const e=this.waitAnimation;this.waitAnimation=void 0,this.play(null!=e?e:this.times,this.waitLoop)}this.waitStop&&(this.waitStop=!1,this.stop())}get animate(){return this._animate}gotoAndPlay(e){this.animate.gotoAndPlay(e)}gotoAndStop(e){this.animate.gotoAndStop(e)}get currentFrame(){var e,t;return null===(t=null===(e=this.animate)||void 0===e?void 0:e.animatedSprite)||void 0===t?void 0:t.currentFrame}get totalFrames(){var e,t;return null===(t=null===(e=this.animate)||void 0===e?void 0:e.animatedSprite)||void 0===t?void 0:t.totalFrames}}m.componentName="SpriteAnimation",a([t.type("string"),o("design:type",String)],m.prototype,"resource",void 0),a([t.type("boolean"),o("design:type",Boolean)],m.prototype,"autoPlay",void 0),a([t.type("number"),t.step(10),o("design:type",Number)],m.prototype,"speed",void 0),a([t.type("boolean"),o("design:type",Boolean)],m.prototype,"forwards",void 0);const c="_s|r|c_";e.resource.registerInstance(e.RESOURCE_TYPE.SPRITE_ANIMATION,({name:e,data:t})=>new Promise(i=>{var n;const a=t.json.data,o=t.image instanceof s.Texture?t.image:s.Texture.from(t.image);let r=a.frames||{};if(Array.isArray(r)){const e={};for(const t of r){const i=null!==(n=t.filename)&&void 0!==n?n:t.name;i&&(e[i]=t)}r=e}const m=a.animations||{},p={},d={};for(const t in r){d[e+c+t]=r[t]}for(const t in m){const i=[];if(m[t]&&m[t].length>=0)for(const n of m[t]){const t=e+c+n;i.push(t)}p[t]=i}const h=new s.Spritesheet(o,Object.assign(Object.assign({},a),{frames:d,animations:p}));h.parse().then(()=>{const{textures:e}=h,t=[];for(const i in e)t.push(e[i]);i(t)})})),e.resource.registerDestroy(e.RESOURCE_TYPE.SPRITE_ANIMATION,({instance:e})=>{if(e)for(const t of e)t.destroy(!0)});let p=class extends i.Renderer{constructor(){super(...arguments),this.name="SpriteAnimationSystem",this.animates={},this.autoPlay={}}init(){this.renderSystem=this.game.getSystem(i.RendererSystem),this.renderSystem.rendererManager.register(this)}rendererUpdate(e){const{width:t,height:i}=e.transform.size;this.animates[e.id]&&(this.animates[e.id].animatedSprite.width=t,this.animates[e.id].animatedSprite.height=i)}componentChanged(t){return r(this,void 0,void 0,function*(){const i=t.gameObject.id;if("SpriteAnimation"===t.componentName){const n=t.component;if(this.autoPlay[t.gameObject.id]=n.autoPlay,t.type===e.OBSERVER_TYPE.ADD){const s=this.increaseAsyncId(i),{instance:a}=yield e.resource.getResource(n.resource);if(!this.validateAsyncId(i,s))return;a||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.add({frames:a,id:t.gameObject.id,component:n})}else if(t.type===e.OBSERVER_TYPE.CHANGE)if(t.prop&&"speed"===t.prop.prop[0])this.animates[t.gameObject.id].speed=1e3/60/n.speed;else{const s=this.increaseAsyncId(i),{instance:a}=yield e.resource.getResource(n.resource);if(!this.validateAsyncId(i,s))return;a||console.error(`GameObject:${t.gameObject.name}'s Img resource load error`),this.change({frames:a,id:t.gameObject.id,component:n})}else t.type===e.OBSERVER_TYPE.REMOVE&&(this.increaseAsyncId(i),this.remove(t.gameObject.id))}})}add({frames:e,id:t,component:i}){const s=new n.SpriteAnimation({frames:e});this.animates[t]=s,this.containerManager.getContainer(t).addChildAt(s.animatedSprite,0),s.animatedSprite.onComplete=()=>{i.emit("complete")},s.animatedSprite.onFrameChange=()=>{i.emit("frameChange")},s.animatedSprite.onLoop=()=>{i.emit("loop")},i.animate=this.animates[t],this.animates[t].speed=1e3/60/i.speed,this.autoPlay[t]&&s.animatedSprite.play()}change({frames:e,id:t,component:i}){this.remove(t,!0),this.add({frames:e,id:t,component:i})}remove(e,t){const i=this.animates[e];i&&(this.autoPlay[e]=i.animatedSprite.playing,this.containerManager.getContainer(e).removeChild(i.animatedSprite),i.animatedSprite.destroy(),delete this.animates[e],t||delete this.autoPlay[e])}};p.systemName="SpriteAnimationSystem",p=a([e.decorators.componentObserver({SpriteAnimation:["speed","resource"]})],p);var d=p;exports.SpriteAnimation=m,exports.SpriteAnimationSystem=d;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("@eva/eva.js"),e=require("@eva/inspector-decorator"),i=require("@eva/plugin-renderer"),s=require("@eva/renderer-adapter"),n=require("pixi.js");function a(t,e,i,s){var n,a=arguments.length,o=a<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,s);else for(var r=t.length-1;r>=0;r--)(n=t[r])&&(o=(a<3?n(o):a>3?n(e,i,o):n(e,i))||o);return a>3&&o&&Object.defineProperty(e,i,o),o}function o(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)}function r(t,e,i,s){return new(i||(i=Promise))(function(n,a){function o(t){try{h(s.next(t))}catch(t){a(t)}}function r(t){try{h(s.throw(t))}catch(t){a(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i(function(t){t(e)})).then(o,r)}h((s=s.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class h extends t.Component{constructor(t){super(t),this.resource="",this.autoPlay=!0,this.speed=100,this.forwards=!1,this.animations={},this.waitPlay=!1,this.waitLoop=!1,this.waitStop=!1,this.times=1/0,this.count=0,this.complete=!1,this.activeClipLoop=!1,this.listenerBound=!1,this.init(t)}init(t){t&&Object.assign(this,t),this.listenerBound||(this.listenerBound=!0,this.on("loop",()=>{var t;this.complete||(this.activeClip?this.activeClipLoop?this.animate.gotoAndPlay(this.activeClip.start):(this.animate.gotoAndStop(this.activeClip.end),this.finish()):++this.count>=this.times&&(this.forwards?this.gotoAndStop(this.totalFrames-1):null===(t=this.animate)||void 0===t||t.stop(),this.finish()))}),this.on("complete",()=>{var t;null===(t=this.onComplete)||void 0===t||t.call(this)}),this.on("frameChange",()=>{var t;const e=this.currentFrame;null===(t=this.onFrameChange)||void 0===t||t.call(this,e),!this.complete&&this.activeClip&&e>=this.activeClip.end&&(this.activeClipLoop?this.animate.gotoAndPlay(this.activeClip.start):(this.animate.stop(),e>this.activeClip.end&&this.animate.gotoAndStop(this.activeClip.end),this.finish()))}))}finish(){this.complete||(this.complete=!0,this.emit("complete"))}_handleRendererComplete(){this.finish()}isValidClip(t){return Number.isInteger(t.start)&&Number.isInteger(t.end)&&t.start>=0&&t.start<=t.end&&t.end<this.totalFrames}play(t=1/0,e=!1){const i="number"==typeof t?t:e?1/0:1;let s;if("string"==typeof t){this.currentAnimation=t,this.activeClip=void 0,this.activeClipLoop=!1;const i=this.animations[t];i&&(s=i.start,this.animate&&this.isValidClip(i)&&(this.activeClip=i,this.activeClipLoop=e),void 0!==i.speed&&(this.speed=i.speed))}else this.currentAnimation=void 0,this.activeClip=void 0,this.activeClipLoop=!1;0!==i&&(this.times=i,this.animate?(this.complete&&void 0===s&&this.gotoAndStop(0),this.count=0,this.complete=!1,void 0!==s?this.animate.gotoAndPlay(s):this.animate.play()):(this.waitPlay=!0,this.waitAnimation="string"==typeof t?t:void 0,this.waitLoop=e))}stop(){this.animate?this.animate.stop():this.waitStop=!0}set animate(t){if(this._animate=t,this.waitPlay){this.waitPlay=!1;const t=this.waitAnimation;this.waitAnimation=void 0,this.play(null!=t?t:this.times,this.waitLoop)}this.waitStop&&(this.waitStop=!1,this.stop())}get animate(){return this._animate}gotoAndPlay(t){this.animate.gotoAndPlay(t)}gotoAndStop(t){this.animate.gotoAndStop(t)}get currentFrame(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.currentFrame}get totalFrames(){var t,e;return null===(e=null===(t=this.animate)||void 0===t?void 0:t.animatedSprite)||void 0===e?void 0:e.totalFrames}}h.componentName="SpriteAnimation",a([e.type("string"),o("design:type",String)],h.prototype,"resource",void 0),a([e.type("boolean"),o("design:type",Boolean)],h.prototype,"autoPlay",void 0),a([e.type("number"),e.step(10),o("design:type",Number)],h.prototype,"speed",void 0),a([e.type("boolean"),o("design:type",Boolean)],h.prototype,"forwards",void 0);const p="_s|r|c_";t.resource.registerInstance(t.RESOURCE_TYPE.SPRITE_ANIMATION,({name:t,data:e})=>new Promise(i=>{var s;const a=e.json.data,o=e.image instanceof n.Texture?e.image:n.Texture.from(e.image);let r=a.frames||{};if(Array.isArray(r)){const t={};for(const e of r){const i=null!==(s=e.filename)&&void 0!==s?s:e.name;i&&(t[i]=e)}r=t}const h=a.animations||{},c={},m={};for(const e in r){m[t+p+e]=r[e]}for(const e in h){const i=[];if(h[e]&&h[e].length>=0)for(const s of h[e]){const e=t+p+s;i.push(e)}c[e]=i}const d=new n.Spritesheet(o,Object.assign(Object.assign({},a),{frames:m,animations:c}));d.parse().then(()=>{const{textures:t}=d,e=[];for(const i in t)e.push(t[i]);i(e)})})),t.resource.registerDestroy(t.RESOURCE_TYPE.SPRITE_ANIMATION,({instance:t})=>{if(t)for(const e of t)e.destroy(!0)});let c=class extends i.Renderer{constructor(){super(...arguments),this.name="SpriteAnimationSystem",this.animates={},this.autoPlay={}}init(){this.renderSystem=this.game.getSystem(i.RendererSystem),this.renderSystem.rendererManager.register(this)}rendererUpdate(t){const{width:e,height:i}=t.transform.size;this.animates[t.id]&&(this.animates[t.id].animatedSprite.width=e,this.animates[t.id].animatedSprite.height=i)}componentChanged(e){return r(this,void 0,void 0,function*(){const i=e.gameObject.id;if("SpriteAnimation"===e.componentName){const s=e.component;if(this.autoPlay[e.gameObject.id]=s.autoPlay,e.type===t.OBSERVER_TYPE.ADD){const n=this.increaseAsyncId(i),{instance:a}=yield t.resource.getResource(s.resource);if(!this.validateAsyncId(i,n))return;a||console.error(`GameObject:${e.gameObject.name}'s Img resource load error`),this.add({frames:a,id:e.gameObject.id,component:s})}else if(e.type===t.OBSERVER_TYPE.CHANGE)if(e.prop&&"speed"===e.prop.prop[0])this.animates[e.gameObject.id].speed=1e3/60/s.speed;else{const n=this.increaseAsyncId(i),{instance:a}=yield t.resource.getResource(s.resource);if(!this.validateAsyncId(i,n))return;a||console.error(`GameObject:${e.gameObject.name}'s Img resource load error`),this.change({frames:a,id:e.gameObject.id,component:s})}else e.type===t.OBSERVER_TYPE.REMOVE&&(this.increaseAsyncId(i),this.remove(e.gameObject.id))}})}add({frames:t,id:e,component:i}){const n=new s.SpriteAnimation({frames:t});this.animates[e]=n,this.containerManager.getContainer(e).addChildAt(n.animatedSprite,0),n.animatedSprite.onComplete=()=>{i._handleRendererComplete()},n.animatedSprite.onFrameChange=()=>{i.emit("frameChange")},n.animatedSprite.onLoop=()=>{i.emit("loop")},i.animate=this.animates[e],this.animates[e].speed=1e3/60/i.speed,this.autoPlay[e]&&n.animatedSprite.play()}change({frames:t,id:e,component:i}){this.remove(e,!0),this.add({frames:t,id:e,component:i})}remove(t,e){const i=this.animates[t];i&&(this.autoPlay[t]=i.animatedSprite.playing,this.containerManager.getContainer(t).removeChild(i.animatedSprite),i.animatedSprite.destroy(),delete this.animates[t],e||delete this.autoPlay[t])}};c.systemName="SpriteAnimationSystem",c=a([t.decorators.componentObserver({SpriteAnimation:["speed","resource"]})],c);var m=c;exports.SpriteAnimation=h,exports.SpriteAnimationSystem=m;
@@ -78,6 +78,10 @@ export declare class SpriteAnimation extends Component<SpriteAnimationParams> {
78
78
  private count;
79
79
  /** 是否播放完成 */
80
80
  private complete;
81
+ /** 当前命名动画的闭区间边界 */
82
+ private activeClip?;
83
+ /** 当前命名动画是否循环 */
84
+ private activeClipLoop;
81
85
  private listenerBound;
82
86
  constructor(params?: SpriteAnimationParams);
83
87
  /**
@@ -89,6 +93,9 @@ export declare class SpriteAnimation extends Component<SpriteAnimationParams> {
89
93
  * @param obj.forwards - 是否停在最后一帧
90
94
  */
91
95
  init(obj?: SpriteAnimationParams): void;
96
+ private finish;
97
+ /* Excluded from this release type: _handleRendererComplete */
98
+ private isValidClip;
92
99
  play(nameOrTimes?: string | number, loop?: boolean): void;
93
100
  stop(): void;
94
101
  set animate(val: SpriteAnimation_2);
@@ -107,6 +107,8 @@ class SpriteAnimation$2 extends Component {
107
107
  this.count = 0;
108
108
  /** 是否播放完成 */
109
109
  this.complete = false;
110
+ /** 当前命名动画是否循环 */
111
+ this.activeClipLoop = false;
110
112
  this.listenerBound = false;
111
113
  this.init(params);
112
114
  }
@@ -124,6 +126,18 @@ class SpriteAnimation$2 extends Component {
124
126
  this.listenerBound = true;
125
127
  this.on('loop', () => {
126
128
  var _a;
129
+ if (this.complete)
130
+ return;
131
+ if (this.activeClip) {
132
+ if (this.activeClipLoop) {
133
+ this.animate.gotoAndPlay(this.activeClip.start);
134
+ }
135
+ else {
136
+ this.animate.gotoAndStop(this.activeClip.end);
137
+ this.finish();
138
+ }
139
+ return;
140
+ }
127
141
  if (++this.count >= this.times) {
128
142
  if (this.forwards) {
129
143
  this.gotoAndStop(this.totalFrames - 1);
@@ -131,8 +145,7 @@ class SpriteAnimation$2 extends Component {
131
145
  else {
132
146
  (_a = this.animate) === null || _a === void 0 ? void 0 : _a.stop();
133
147
  }
134
- this.complete = true;
135
- this.emit('complete');
148
+ this.finish();
136
149
  }
137
150
  });
138
151
  this.on('complete', () => {
@@ -141,22 +154,64 @@ class SpriteAnimation$2 extends Component {
141
154
  });
142
155
  this.on('frameChange', () => {
143
156
  var _a;
144
- (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, this.currentFrame);
157
+ const frame = this.currentFrame;
158
+ (_a = this.onFrameChange) === null || _a === void 0 ? void 0 : _a.call(this, frame);
159
+ if (!this.complete && this.activeClip && frame >= this.activeClip.end) {
160
+ if (this.activeClipLoop) {
161
+ this.animate.gotoAndPlay(this.activeClip.start);
162
+ }
163
+ else {
164
+ this.animate.stop();
165
+ if (frame > this.activeClip.end) {
166
+ this.animate.gotoAndStop(this.activeClip.end);
167
+ }
168
+ this.finish();
169
+ }
170
+ }
145
171
  });
146
172
  }
147
173
  }
174
+ finish() {
175
+ if (this.complete)
176
+ return;
177
+ this.complete = true;
178
+ this.emit('complete');
179
+ }
180
+ /** @internal Renderer event entry point; keeps late renderer callbacks idempotent. */
181
+ _handleRendererComplete() {
182
+ this.finish();
183
+ }
184
+ isValidClip(clip) {
185
+ return (Number.isInteger(clip.start) &&
186
+ Number.isInteger(clip.end) &&
187
+ clip.start >= 0 &&
188
+ clip.start <= clip.end &&
189
+ clip.end < this.totalFrames);
190
+ }
148
191
  play(nameOrTimes = Infinity, loop = false) {
149
- let times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
192
+ const times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
150
193
  let startFrame;
151
194
  if (typeof nameOrTimes === 'string') {
152
195
  this.currentAnimation = nameOrTimes;
196
+ this.activeClip = undefined;
197
+ this.activeClipLoop = false;
153
198
  const clip = this.animations[nameOrTimes];
154
199
  if (clip) {
155
200
  startFrame = clip.start;
201
+ // Invalid ranges keep the legacy start-only/full-timeline behavior instead of throwing.
202
+ if (this.animate && this.isValidClip(clip)) {
203
+ this.activeClip = clip;
204
+ this.activeClipLoop = loop;
205
+ }
156
206
  if (clip.speed !== undefined)
157
207
  this.speed = clip.speed;
158
208
  }
159
209
  }
210
+ else {
211
+ this.currentAnimation = undefined;
212
+ this.activeClip = undefined;
213
+ this.activeClipLoop = false;
214
+ }
160
215
  if (times === 0) {
161
216
  return;
162
217
  }
@@ -167,17 +222,17 @@ class SpriteAnimation$2 extends Component {
167
222
  this.waitLoop = loop;
168
223
  }
169
224
  else {
170
- if (this.complete) {
225
+ if (this.complete && startFrame === undefined) {
171
226
  this.gotoAndStop(0);
172
227
  }
228
+ this.count = 0;
229
+ this.complete = false;
173
230
  if (startFrame !== undefined) {
174
231
  this.animate.gotoAndPlay(startFrame);
175
232
  }
176
233
  else {
177
234
  this.animate.play();
178
235
  }
179
- this.count = 0;
180
- this.complete = false;
181
236
  }
182
237
  }
183
238
  stop() {
@@ -360,7 +415,7 @@ let SpriteAnimation = class SpriteAnimation extends Renderer {
360
415
  this.animates[id] = animate;
361
416
  this.containerManager.getContainer(id).addChildAt(animate.animatedSprite, 0);
362
417
  animate.animatedSprite.onComplete = () => {
363
- component.emit('complete');
418
+ component._handleRendererComplete();
364
419
  };
365
420
  animate.animatedSprite.onFrameChange = () => {
366
421
  component.emit('frameChange');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eva/plugin-renderer-sprite-animation",
3
- "version": "2.1.0-beta.1",
3
+ "version": "2.1.0-beta.10",
4
4
  "description": "@eva/plugin-renderer-sprite-animation",
5
5
  "main": "index.js",
6
6
  "module": "dist/plugin-renderer-sprite-animation.esm.js",
@@ -19,9 +19,9 @@
19
19
  "homepage": "https://eva.js.org",
20
20
  "dependencies": {
21
21
  "@eva/inspector-decorator": "^2.0.0-beta.0",
22
- "@eva/plugin-renderer": "2.1.0-beta.1",
23
- "@eva/renderer-adapter": "2.1.0-beta.1",
24
- "@eva/eva.js": "2.1.0-beta.1",
22
+ "@eva/plugin-renderer": "2.1.0-beta.10",
23
+ "@eva/renderer-adapter": "2.1.0-beta.10",
24
+ "@eva/eva.js": "2.1.0-beta.10",
25
25
  "pixi.js": "^8.17.0"
26
26
  }
27
27
  }