From a075010a96558089f014e18db5f01311556e1fec Mon Sep 17 00:00:00 2001 From: Elijah R Date: Sat, 20 Jul 2024 08:32:09 -0400 Subject: [PATCH] Minor animation improvements - Bind nextFrame to window.requestAnimationFrame to prevent hanging if the tab is out of focus - Playing an animation when one is already queued/in progress now cancels the old one instead of throwing an error --- msagent.js/src/agent.ts | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/msagent.js/src/agent.ts b/msagent.js/src/agent.ts index 61ed751..e2f78d9 100644 --- a/msagent.js/src/agent.ts +++ b/msagent.js/src/agent.ts @@ -24,6 +24,7 @@ function randint(min: number, max: number) { class AgentAnimationState { char: Agent; anim: AcsAnimation; + private cancelled: boolean = false; finishCallback: () => void; frameIndex = 0; @@ -41,18 +42,26 @@ class AgentAnimationState { this.nextFrame(); } + cancel() { + this.cancelled = true; + clearTimeout(this.interval); + } + nextFrame() { - this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]); + requestAnimationFrame(() => { + if (this.cancelled) return; + this.char.drawAnimationFrame(this.anim.frameInfo[this.frameIndex++]); - if (this.frameIndex >= this.anim.frameInfo.length) { - this.finishCallback(); - return; - } - - //@ts-ignore - this.interval = setTimeout(() => { - this.nextFrame(); - }, this.anim.frameInfo[this.frameIndex].frameDuration * 10); + if (this.frameIndex >= this.anim.frameInfo.length) { + this.finishCallback(); + return; + } + + //@ts-ignore + this.interval = setTimeout(() => { + this.nextFrame(); + }, this.anim.frameInfo[this.frameIndex].frameDuration * 10); + }); } } @@ -350,7 +359,10 @@ export class Agent { // add promise versions later. playAnimation(index: number, finishCallback: () => void) { - if (this.animState != null) throw new Error('Cannot play multiple animations at once.'); + if (this.animState != null) { + this.animState.cancel(); + this.animState = null; + } let animInfo = this.data.animInfo[index]; // Create and start the animation state