diff options
author | Saivan <savian@me.com> | 2018-05-31 00:13:43 +1000 |
---|---|---|
committer | Saivan <savian@me.com> | 2018-05-31 00:13:43 +1000 |
commit | f20d66d21267ab8e91df2b6f236b28078c0f99e7 (patch) | |
tree | 923c81d63ca8ae2d13590860d4a50fd0363813f1 /src | |
parent | 599ab86152869496f71ef2a4b3af2d695140fcdf (diff) | |
download | svg.js-f20d66d21267ab8e91df2b6f236b28078c0f99e7.tar.gz svg.js-f20d66d21267ab8e91df2b6f236b28078c0f99e7.zip |
The runners step was reimplemented with tests
Diffstat (limited to 'src')
-rw-r--r-- | src/morph.js | 6 | ||||
-rw-r--r-- | src/number.js | 3 | ||||
-rw-r--r-- | src/runner.js | 141 | ||||
-rw-r--r-- | src/timeline.js | 1 |
4 files changed, 78 insertions, 73 deletions
diff --git a/src/morph.js b/src/morph.js index cf674bf..36ab2fa 100644 --- a/src/morph.js +++ b/src/morph.js @@ -235,8 +235,8 @@ SVG.extend(SVG.MorphableTypes, { .from(this.valueOf()) .to(val, args) }, - fromArray: function () { - this.constructor.apply(this, arguments) + fromArray: function (arr) { + this.constructor.call(this, arr) return this } }) @@ -352,8 +352,6 @@ fn () => { .after(fn) } - - When you start an element has a base matrix B - which starts as the identity If you modify the matrix, then we have: diff --git a/src/number.js b/src/number.js index 1a24954..7fef7f2 100644 --- a/src/number.js +++ b/src/number.js @@ -3,6 +3,7 @@ SVG.Number = SVG.invent({ // Initialize create: function (value, unit) { + unit = Array.isArray(value) ? value[1] : unit value = Array.isArray(value) ? value[0] : value // initialize defaults @@ -48,7 +49,7 @@ SVG.Number = SVG.invent({ return this.toString() }, // Convert to primitive toArray: function () { - return [this.value] + return [this.value, this.unit] }, valueOf: function () { return this.value diff --git a/src/runner.js b/src/runner.js index 1b0ce90..e77bcb3 100644 --- a/src/runner.js +++ b/src/runner.js @@ -6,9 +6,6 @@ SVG.easing = { '<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 } } -// function sanitise - - SVG.Runner = SVG.invent({ inherit: SVG.EventTarget, @@ -168,13 +165,12 @@ SVG.Runner = SVG.invent({ return this }, - // FIXME: When not using queue the example is not working anymore during: function (fn) { - return this.on('during', fn, this) + return this.queue(null, fn) }, after (fn) { - return this.on('finish', fn, this) + return this.on('finish', fn) }, /* @@ -184,78 +180,89 @@ SVG.Runner = SVG.invent({ */ time: function (time) { - if (time == null) return this._time + if (time == null) { + return this._time + } let dt = time - this._time this.step(dt) return this }, - step: function (dt) { + duration: function () { + return this._times * (this._wait + this._duration) - this._wait + }, - // If there is no duration, we are in declarative mode and dt has to be - // positive always, so if its negative, we ignore it. - if (this._isDeclarative && dt < 0) return this - - // When no duration is set, all numbers including this._time end up NaN - // and that makes step returning at the first check - if(!this._isDeclarative) { - // If the user gives us a huge dt, figure out how many full loops - // have passed during this time. A full loop is the time required to - var absolute = this._time + dt + this._wait - var period = this._duration + this._wait - var nPeriods = Math.floor(absolute / period) - this._loopsDone += nPeriods - this._time = ((absolute % period) + period) % period - this._wait - - // FIXME: Without that it loops forever even without trying to loop - if(this._loopsDone >= this._times) this._time = Infinity - - // Make sure we reverse the code if we had an odd number of loops - this.reversed = (nPeriods % 2 === 0) ? this.reversed : !this.reversed + position: function (p) { + var loopDuration = this._duration + this._wait + if (p == null) { + var loopsDone = Math.floor(this._time / loopDuration) + var relativeTime = (this._time - loopsDone * loopDuration) + var position = relativeTime / this._duration + return Math.min(loopsDone + position, this._times) } + var whole = Math.floor(p) + var partial = p % 1 + var time = loopDuration * whole + this._duration * partial + return this.time(time) + }, - // Increment the time and read out the parameters - // this._time += dt - var duration = this._duration || Infinity - var time = this._time + absolute: function (p) { + if (p == null) { + return Math.min(1, this._time / this.duration()) + } + return this.time(p * this.duration()) + }, - // Work out if we are in range to run the function - var timeInside = 0 <= time && time <= duration - var finished = time >= duration - var position = finished ? 1 : time / duration + step: function (dt) { - // Deal with reversing - position = this._reversing ? 1 - position : position + // Update the time + dt = dt == null ? 16 : dt + this._time += dt + + // If we exceed the duration, just set the time to the duration + var duration = this.duration() + this._time = Math.min(duration, this._time) + + // Deal with non-declarative animations directly + // Explanation: https://www.desmos.com/calculator/wrnybkho4f + // Figure out how many loops we've done + var loopDuration = this._duration + this._wait + var loopsDone = Math.floor(this._time / loopDuration) + + // Figure out if we need to run the animation backwards + var swinging = this._swing && (loopsDone % 2 === 1) + var reversing = (swinging && !this._reversing) + || (!swinging && this._reversing) + + // Figure out the position + var position = this._time < duration + ? (this._time % loopDuration) / this._duration + : 1 + var clipPosition = Math.min(1, position) + var stepperPosition = reversing ? 1 - clipPosition : clipPosition + + // Figure out if we need to run + var runNow = this._lastPosition !== stepperPosition && this._time >= 0 + this._lastPosition = stepperPosition + + // Figure out if we just started + var justStarted = this._lastTime < 0 && this._time > 0 + var justFinished = this._lastTime < this._time && this.time > duration + this._lastTime = this._time + if (justStarted) { + this.fire('start', this) + } - // If we are on the rising edge, initialise everything, otherwise, - // initialise only what needs to be initialised on the rising edge - var justFinished = this._last <= duration && finished + // Call initialise and the run function this._initialise() - this._last = time - - // If we haven't started yet or we are over the time, just exit - if(!timeInside && !justFinished) return finished - - // Run the runner and store the last time it was run - var runnersFinished = this._run(this._isDeclarative ? dt : position) - finished = (this._isDeclarative && runnersFinished) - || (!this._isDeclarative && finished) - - // Set whether this runner is complete or not - this.done = finished - - // Deal with looping if we just finished an animation - if (this.done && ++this._loopsDone < this._times && !this._isDeclarative) { - - // If swinging, toggle the reversing flag - this._reversing = this._swing ? !this._reversing : this._reversing - - // Set the time to the wait time, and mark that we are not done yet - this._time = - this._wait - this.done = false + if ( runNow || this._isDeclarative ) { + var converged = this._run(this._isDeclarative ? dt : stepperPosition) + this.fire('step', this) } - // Fire finished event if finished + // Work out if we are done and return this + this.done = (converged && this._isDeclarative) + || (this._time >= duration && !justFinished && !this._isDeclarative) if (this.done) { this.fire('finish', this) } @@ -267,10 +274,7 @@ SVG.Runner = SVG.invent({ }, reverse: function (reverse) { - if (reverse === this._haveReversed) return this this._reversing = reverse == null ? !this._reversing : reverse - this._waitReverse = reverse == null ? !this._waitReverse : reverse - this._haveReversed = reverse == null ? this._haveReversed : null return this }, @@ -335,7 +339,8 @@ SVG.Runner = SVG.invent({ if(this._history[method]) { this._history[method].morpher.to(target) this._history[method].caller.finished = false - this.timeline()._continue() + var timeline = this.timeline() + timeline && timeline._continue() return true } return false diff --git a/src/timeline.js b/src/timeline.js index 864ca71..f3c1cdf 100644 --- a/src/timeline.js +++ b/src/timeline.js @@ -139,6 +139,7 @@ SVG.Timeline = SVG.invent({ seek (dt) { this._time += dt + this._continue() return this }, |