diff options
author | Ulrich-Matthias Schäfer <ulima.ums@googlemail.com> | 2018-11-22 15:56:39 +0100 |
---|---|---|
committer | Ulrich-Matthias Schäfer <ulima.ums@googlemail.com> | 2018-11-22 15:56:39 +0100 |
commit | d5c01a7848154d240f434b38d802fdb65727fd7f (patch) | |
tree | ab1984c2af5274bebcce3469f1165dc77c1237fd /src | |
parent | da216c2af803c50ee4bc82ec0e954a1efc1e8a4e (diff) | |
download | svg.js-d5c01a7848154d240f434b38d802fdb65727fd7f.tar.gz svg.js-d5c01a7848154d240f434b38d802fdb65727fd7f.zip |
fix Timeline so that play, pause, stop, reverse... work correctly. Update runners accordingly
Diffstat (limited to 'src')
-rw-r--r-- | src/animation/Animator.js | 4 | ||||
-rw-r--r-- | src/animation/Runner.js | 14 | ||||
-rw-r--r-- | src/animation/Timeline.js | 54 |
3 files changed, 51 insertions, 21 deletions
diff --git a/src/animation/Animator.js b/src/animation/Animator.js index 9b460f5..1392daa 100644 --- a/src/animation/Animator.js +++ b/src/animation/Animator.js @@ -43,11 +43,11 @@ const Animator = { }, cancelFrame (node) { - Animator.frames.remove(node) + node != null && Animator.frames.remove(node) }, clearTimeout (node) { - Animator.timeouts.remove(node) + node != null && Animator.timeouts.remove(node) }, _draw (now) { diff --git a/src/animation/Runner.js b/src/animation/Runner.js index 47929fd..63c95d6 100644 --- a/src/animation/Runner.js +++ b/src/animation/Runner.js @@ -50,6 +50,9 @@ export default class Runner extends EventTarget { this._time = 0 this._last = 0 + // At creation, the runner is in reseted state + this._reseted = true + // Save transforms applied to this runner this.transforms = new Matrix() this.transformId = 1 @@ -276,11 +279,15 @@ export default class Runner extends EventTarget { // Call initialise and the run function if (running || declarative) { + // Runner is running. So its not in reseted state anymore + this._reseted = false + this._initialise(running) // clear the transforms on this runner so they dont get added again and again this.transforms = new Matrix() var converged = this._run(declarative ? dt : position) + this.fire('step', this) } // correct the done flag here @@ -292,6 +299,13 @@ export default class Runner extends EventTarget { return this } + reset () { + if (this._reseted) return this + this.loops(0) + this._reseted = true + return this + } + finish () { return this.step(Infinity) } diff --git a/src/animation/Timeline.js b/src/animation/Timeline.js index a0d8069..bafd319 100644 --- a/src/animation/Timeline.js +++ b/src/animation/Timeline.js @@ -38,6 +38,9 @@ export default class Timeline extends EventTarget { this._time = 0 this._lastSourceTime = 0 this._lastStepTime = 0 + + // Make sure that step is always called in class context + this._step = this._step.bind(this) } // schedules a runner on the timeline @@ -92,7 +95,7 @@ export default class Timeline extends EventTarget { this._runners[runner.id] = { persist: this.persist(), runner: runner, - start: absoluteStartTime + start: absoluteStartTime// + delay } // Save order and continue @@ -115,23 +118,23 @@ export default class Timeline extends EventTarget { play () { // Now make sure we are not paused and continue the animation this._paused = false + this._lastSourceTime = this._timeSource() return this._continue() } pause () { - // Cancel the next animation frame and pause - this._nextFrame = null this._paused = true - return this + return this._continue() } stop () { - // Cancel the next animation frame and go to start + // Go to start and pause this.seek(-this._time) return this.pause() } finish () { + // Go to Infinity and pause this.seek(Infinity) return this.pause() } @@ -152,7 +155,8 @@ export default class Timeline extends EventTarget { seek (dt) { this._time += dt - return this._continue() + // this._lastStepTime = this._time + return this._continue(true) } time (time) { @@ -173,18 +177,22 @@ export default class Timeline extends EventTarget { return this } - _step () { - // If the timeline is paused, just do nothing - if (this._paused) return - + _step (immediateStep = false) { // Get the time delta from the last time and update the time var time = this._timeSource() var dtSource = time - this._lastSourceTime + + if (immediateStep) dtSource = 0 + var dtTime = this._speed * dtSource + (this._time - this._lastStepTime) this._lastSourceTime = time - // Update the time - this._time += dtTime + // Only update the time if we use the timeSource. + // Otherwise use the current time + if (!immediateStep) { + // Update the time + this._time += dtTime + } this._lastStepTime = this._time this.fire('time', this._time) @@ -201,8 +209,13 @@ export default class Timeline extends EventTarget { let dtToStart = this._time - runnerInfo.start // Dont run runner if not started yet - if (dtToStart < 0) { + if (dtToStart <= 0) { runnersLeft = true + + // This is for the case that teh timeline was seeked so that the time + // is now before the startTime of the runner. Thats why we need to set + // the runner to position 0 + runner.reset() continue } else if (dtToStart < dt) { // Adjust dt to make sure that animation is on point @@ -231,22 +244,25 @@ export default class Timeline extends EventTarget { } } - // Get the next animation frame to keep the simulation going if (runnersLeft) { - this._nextFrame = Animator.frame(this._step.bind(this)) + this._continue() } else { this.fire('finished') this._nextFrame = null } + return this } // Checks if we are running and continues the animation - _continue () { + _continue (immediateStep = false) { + Animator.cancelFrame(this._nextFrame) + this._nextFrame = null + + if (immediateStep) return this._step(true) if (this._paused) return this - if (!this._nextFrame) { - this._nextFrame = Animator.frame(this._step.bind(this)) - } + + this._nextFrame = Animator.frame(this._step) return this } |