@eva/plugin-renderer-sprite-animation 2.1.0-beta.7 → 2.1.0-beta.9

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.
@@ -164,6 +164,7 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
164
164
  this.times = Infinity;
165
165
  this.count = 0;
166
166
  this.complete = false;
167
+ this.activeClipLoop = false;
167
168
  this.listenerBound = false;
168
169
  this.init(params);
169
170
  }
@@ -173,14 +174,23 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
173
174
  this.listenerBound = true;
174
175
  this.on('loop', () => {
175
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
+ }
176
187
  if (++this.count >= this.times) {
177
188
  if (this.forwards) {
178
189
  this.gotoAndStop(this.totalFrames - 1);
179
190
  } else {
180
191
  (_a = this.animate) === null || _a === void 0 ? void 0 : _a.stop();
181
192
  }
182
- this.complete = true;
183
- this.emit('complete');
193
+ this.finish();
184
194
  }
185
195
  });
186
196
  this.on('complete', () => {
@@ -189,20 +199,53 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
189
199
  });
190
200
  this.on('frameChange', () => {
191
201
  var _a;
192
- (_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
+ }
193
215
  });
194
216
  }
195
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
+ }
196
229
  play(nameOrTimes = Infinity, loop = false) {
197
- let times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
230
+ const times = typeof nameOrTimes === 'number' ? nameOrTimes : loop ? Infinity : 1;
198
231
  let startFrame;
199
232
  if (typeof nameOrTimes === 'string') {
200
233
  this.currentAnimation = nameOrTimes;
234
+ this.activeClip = undefined;
235
+ this.activeClipLoop = false;
201
236
  const clip = this.animations[nameOrTimes];
202
237
  if (clip) {
203
238
  startFrame = clip.start;
239
+ if (this.animate && this.isValidClip(clip)) {
240
+ this.activeClip = clip;
241
+ this.activeClipLoop = loop;
242
+ }
204
243
  if (clip.speed !== undefined) this.speed = clip.speed;
205
244
  }
245
+ } else {
246
+ this.currentAnimation = undefined;
247
+ this.activeClip = undefined;
248
+ this.activeClipLoop = false;
206
249
  }
207
250
  if (times === 0) {
208
251
  return;
@@ -213,16 +256,16 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
213
256
  this.waitAnimation = typeof nameOrTimes === 'string' ? nameOrTimes : undefined;
214
257
  this.waitLoop = loop;
215
258
  } else {
216
- if (this.complete) {
259
+ if (this.complete && startFrame === undefined) {
217
260
  this.gotoAndStop(0);
218
261
  }
262
+ this.count = 0;
263
+ this.complete = false;
219
264
  if (startFrame !== undefined) {
220
265
  this.animate.gotoAndPlay(startFrame);
221
266
  } else {
222
267
  this.animate.play();
223
268
  }
224
- this.count = 0;
225
- this.complete = false;
226
269
  }
227
270
  }
228
271
  stop() {
@@ -404,7 +447,7 @@ var _EVA_IIFE_spriteAnimation = function (exports, eva_js, pluginRenderer, rende
404
447
  this.animates[id] = animate;
405
448
  this.containerManager.getContainer(id).addChildAt(animate.animatedSprite, 0);
406
449
  animate.animatedSprite.onComplete = () => {
407
- component.emit('complete');
450
+ component._handleRendererComplete();
408
451
  };
409
452
  animate.animatedSprite.onFrameChange = () => {
410
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,"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 d(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 m(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);d(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([m("string"),s("design:type",String)],u.prototype,"resource",void 0),r([m("boolean"),s("design:type",Boolean)],u.prototype,"autoPlay",void 0),r([m("number"),function(t){return l({step:t})}(10),s("design:type",Number)],u.prototype,"speed",void 0),r([m("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={},d={};for(const e in a){d[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 m=new o.Spritesheet(s,_extends(_extends({},r),{frames:d,animations:p}));m.parse().then(()=>{const{textures:t}=m,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.7",
3
+ "version": "2.1.0-beta.9",
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.7",
23
- "@eva/renderer-adapter": "2.1.0-beta.7",
24
- "@eva/eva.js": "2.1.0-beta.7",
22
+ "@eva/plugin-renderer": "2.1.0-beta.9",
23
+ "@eva/renderer-adapter": "2.1.0-beta.9",
24
+ "@eva/eva.js": "2.1.0-beta.9",
25
25
  "pixi.js": "^8.17.0"
26
26
  }
27
27
  }